🐐 Modulo
This commit is contained in:
@@ -396,6 +396,30 @@ CentValue cent_div_frac(CentValue a, CentValue b) {
|
||||
return frac_reduce(an * bd, ad * bn);
|
||||
}
|
||||
|
||||
CentValue cent_mod(CentValue a, CentValue b) {
|
||||
if (a.type != CENT_INT || b.type != CENT_INT)
|
||||
cent_type_error("'RELIQVVM' requires two integers");
|
||||
if (b.ival == 0)
|
||||
cent_runtime_error("modulo by zero");
|
||||
return cent_int(a.ival % b.ival);
|
||||
}
|
||||
|
||||
CentValue cent_mod_frac(CentValue a, CentValue b) {
|
||||
long an, ad, bn, bd;
|
||||
to_frac(a, &an, &ad); to_frac(b, &bn, &bd);
|
||||
if (bn == 0) cent_runtime_error("modulo by zero");
|
||||
/* a/b mod c/d over a common denominator ad*bd:
|
||||
num_a = an*bd, num_b = bn*ad
|
||||
result = (num_a - floor(num_a/num_b) * num_b) / (ad*bd)
|
||||
Use floored division so the result matches Python's Fraction.__mod__. */
|
||||
long num_a = an * bd;
|
||||
long num_b = bn * ad;
|
||||
long q = num_a / num_b;
|
||||
if ((num_a % num_b != 0) && ((num_a < 0) != (num_b < 0))) q -= 1;
|
||||
long new_num = num_a - q * num_b;
|
||||
return frac_reduce(new_num, ad * bd);
|
||||
}
|
||||
|
||||
CentValue cent_eq(CentValue a, CentValue b) {
|
||||
if ((a.type == CENT_INT || a.type == CENT_FRAC) &&
|
||||
(b.type == CENT_INT || b.type == CENT_FRAC)) {
|
||||
@@ -414,6 +438,11 @@ CentValue cent_eq(CentValue a, CentValue b) {
|
||||
}
|
||||
}
|
||||
|
||||
CentValue cent_neq(CentValue a, CentValue b) {
|
||||
CentValue r = cent_eq(a, b);
|
||||
return cent_bool(!r.bval);
|
||||
}
|
||||
|
||||
CentValue cent_lt(CentValue a, CentValue b) {
|
||||
if ((a.type == CENT_INT || a.type == CENT_FRAC || a.type == CENT_NULL) &&
|
||||
(b.type == CENT_INT || b.type == CENT_FRAC || b.type == CENT_NULL)) {
|
||||
|
||||
Reference in New Issue
Block a user