From ae09800483c3a5df8d31e400b7a3be87a9dc5814 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 16 May 2025 19:59:40 -0700 Subject: 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. --- arith.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/arith.c b/arith.c index ad7e3e69..a0d2ee10 100644 --- a/arith.c +++ b/arith.c @@ -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); -- cgit v1.2.3