diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2025-05-16 19:59:40 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2025-05-16 19:59:40 -0700 |
commit | ae09800483c3a5df8d31e400b7a3be87a9dc5814 (patch) | |
tree | 806f0dbe4e0411a7def5c1604ad9b94dacb9f4b2 | |
parent | 410116deffa838061b8380f4d794a1b0ed12dbee (diff) | |
download | txr-ae09800483c3a5df8d31e400b7a3be87a9dc5814.tar.gz txr-ae09800483c3a5df8d31e400b7a3be87a9dc5814.tar.bz2 txr-ae09800483c3a5df8d31e400b7a3be87a9dc5814.zip |
arith: logtrunc: issues with short-circuiting to zero.
* arith.c (logtrunc): Firstly, the correct condition
for trivially returning zero is bits <= 0, not bits < 0.
Secondly, we don't want to do this upfront. In the
case we have a struct with user-defined arithmetic,
the method must be called. It might return a different
kind of zero.
-rw-r--r-- | arith.c | 14 |
1 files changed, 8 insertions, 6 deletions
@@ -3867,21 +3867,20 @@ bad: val logtrunc(val a, val bits) { val self = logtrunc_s; - cnum an, bn; - val b; const cnum num_mask = (NUM_MAX << 1) | 1; if (!fixnump(bits)) goto bad2; - bn = c_n(bits); - - if (bn < 0) - return zero; switch (type(a)) { mp_err mpe; + cnum an, bn; + val b; case NUM: + bn = c_n(bits); + if (bn <= 0) + return zero; an = c_n(a); if (bn <= NUM_BIT) { cnum mask = num_mask >> (NUM_BIT - bn); @@ -3890,6 +3889,9 @@ val logtrunc(val a, val bits) a = bignum(an); /* fallthrough */ case BGNUM: + bn = c_n(bits); + if (bn <= 0) + return zero; b = make_ubignum(); if ((mpe = mp_trunc(mp(a), mp(b), bn)) != MP_OKAY) do_mp_error(self, mpe); |