c tier: rationals on int/int division — matches python lumbda
num_div for two integers used to fall back to double when the quotient wasn't exact. R7RS / python lumbda require exact-in → exact-out for /. Fixed: the rational_normalize path was already wired for the is_exact branch; the int/int branch now calls it too instead of make_double. (/ 67 7) → 67/7 (was 9.5714285714285712) (/ 1 3) → 1/3 (was 0.33333…) (/ 6 2) → 3 (exact stays integer) (+ 1/3 1/6) → 1/2 (rational arithmetic propagates) C native + C-WASM tier now match python lumbda on / between integers. asm tier rationals remain pending — that needs bignums in asm first. native c-test: 205/205 still passes.
This commit is contained in:
parent
ef8b9b5819
commit
991ef661e3
3 changed files with 9 additions and 7 deletions
16
c/types.c
16
c/types.c
|
|
@ -419,18 +419,20 @@ Value num_mul(Value a, Value b) {
|
|||
}
|
||||
|
||||
Value num_div(Value a, Value b) {
|
||||
/* Integer / integer that divides cleanly stays integer (matches Python /
|
||||
* Scheme semantics for `/` between exacts when the quotient is exact).
|
||||
* For bignum case we treat as exact division (truncating to integer when
|
||||
* quotient is exact, else fall back to double for now — secp256k1 ops
|
||||
* never use fractional bignum). */
|
||||
/* Integer / integer that divides cleanly stays integer; otherwise we
|
||||
* promote to an exact rational (matches Python lumbda and R7RS:
|
||||
* `/` between exacts produces an exact result). The previous code
|
||||
* fell back to double for non-divisible int/int — that broke parity
|
||||
* with the Python tier on (/ 67 7), (/ 1 3), etc. */
|
||||
if (IS_INTEGER(a) && IS_INTEGER(b)) {
|
||||
if (big_is_zero(b)) lisp_error("division by zero");
|
||||
Value q = big_quotient(a, b);
|
||||
Value r = big_remainder(a, b);
|
||||
if (big_is_zero(r)) return q;
|
||||
/* Inexact fallback. */
|
||||
return make_double(as_number_double(a) / as_number_double(b));
|
||||
int64_t an, ad, bn, bd;
|
||||
to_rational(a, &an, &ad);
|
||||
to_rational(b, &bn, &bd);
|
||||
return rational_normalize(an * bd, ad * bn);
|
||||
}
|
||||
if (is_exact(a) && is_exact(b)) {
|
||||
int64_t an, ad, bn, bd;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue