Commit graph

6 commits

Author SHA1 Message Date
Alex Shinn
4fc7181c2c Fix in sexp_bignum_quot_rem when the numerator and divisor are equal.
Fixes issue #269.
2015-06-15 23:31:46 +09:00
Alex Shinn
01df2fec44 Merge pull request #251 from ilammy/overflow-fixes
Fixed a couple of integer overflows
2015-04-15 17:14:58 +09:00
Alex Shinn
4dda923081 Updating copyright years. 2015-04-09 01:28:02 +09:00
ilammy
8329ee9fd6 Do not lose carry bit in addition edge case
Previous code was losing the carry bit in 'all ones' case, when adata[i]
= bdata[i] = SEXP_UINT_T_MAX, and carry = 1 too. In this case expression
(SEXP_UINT_T_MAX - bdata[i] - carry) overflows and yields an incorrect
value SEXP_UINT_T_MAX which results into carry being incorrectly set to
0 after addition.

We need to avoid the second overflow when calculating the new value of
the carry bit. One way to do this is at first check for the overflow in
(adata[i] + bdata[i]), and then throw in the (previous) carry bit.

I have also given "n" more expressive name and added a comment about
the reason why we need that temporary variable.
2015-03-26 02:30:48 +02:00
ilammy
a1ec8ff493 Avoid overflow when doing sexp_fx_abs()
Naturally, fixed-width integer arithmetics can overflow. Chibi handles
it pretty well in general, but one case was missing: it is negation of
the minimal negative number that can be represented as a fixnum. That is,
sexp_fx_neg() must not be applied to sexp_make_fixnum(SEXP_MIN_FIXNUM)
because it overflows and returns an identical fixnum back.

sexp_fx_neg() itself seems to be used right in the current code, but
sexp_fx_abs()--which is defined in terms of sexp_fx_neg()--could be
applied to the forbidden number when used to retrieve an unboxed value
via the sexp_unbox_fixnum(sexp_fx_abs(x)) pattern. So I have added a
separate macro that safely calculates unboxed absolute value of a fixnum,
and replaced sexp_unbox_fixnum(sexp_fx_abs(x)) usages with it.

Current implementation uses two-bit tag for fixnums, plus we need one
bit for the sign, so fixnums have (machine word - 3) significant bits.
Regression tests cover word sizes of 16, 32, 64, and 128 bits (for the
sake of past- and future-proofness).

sexp_bignum_expt() does not have a regression test because we need to
check it with negative exponents like -2^29, so the base must be over
at least 2^(2^29) for the differences to be visible. Fun fact: bignum
representation of such number takes around 1/32 of the available user-
space memory, which makes testing on anything except 32-bit systems
unreasonable (4 TB of RAM anyone?)
2015-03-26 02:30:48 +02:00
Alex Shinn
2922ed591d Forgot to install regexp (patch from Lorenzo) 2015-01-26 08:06:59 +09:00