diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-01-18 10:16:28 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-01-18 10:16:28 -0800 |
commit | 6c8b83de506a6d71024d4a6aaa35456cba58ebb8 (patch) | |
tree | 102a01e8b2b8b7df87a912f054f3e62974ba37cb | |
parent | 7e80d2f3c312b44cb72c156f5212e63fe5bc6765 (diff) | |
download | txr-6c8b83de506a6d71024d4a6aaa35456cba58ebb8.tar.gz txr-6c8b83de506a6d71024d4a6aaa35456cba58ebb8.tar.bz2 txr-6c8b83de506a6d71024d4a6aaa35456cba58ebb8.zip |
Fix bug in bignum single-digit addition.
Sigh; this is a continuation of the same topic that was
addressed in November 14, 2016: "Fix bug in bignum addition".
Commit SHA: c1259dc059586bf0187d52e56d71199a4db63cde.
Though I fixed s_mp_add, s_mp_add_d has the same problem. Two
digit-sized quantities are added together in the digit-sized
type, and so the CARRYOUT(w) from the result is always zero.
This bug causes the following consequences (using behavior
under 32 bit as an example):
1. Wrong arithmetic:
(succ (pred (expt 2 32)) -> 0
2. Wrong conversion from decimal:
4294967296 -> 0
4294967297 -> 1
4294967298 -> 2
4294967299 -> 3
As well as all values that begin with the above digit
sequences.
4. Wrong conversion from floating-point.
(toint 4294967296.0) -> 0
* mpi/mpi.c (s_mp_add_d): Add missing cast to the initial
addition that adds the incoming digit d to the least
significant limb of the bignum, so that the addition is done
in the wider mp_word type, allowing CARRYOUT(w) to calculate a
nonzero k value.
-rw-r--r-- | mpi/mpi.c | 2 |
1 files changed, 1 insertions, 1 deletions
@@ -3300,7 +3300,7 @@ mp_err s_mp_add_d(mp_int *mp, mp_digit d) /* unsigned digit addition */ mp_size ix = 1, used = USED(mp); mp_digit *dp = DIGITS(mp); - w = dp[0] + d; + w = convert(mp_word, dp[0]) + d; dp[0] = ACCUM(w); k = CARRYOUT(w); |