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 | 22a3cad47355ebbb6aef86b503d98368e8110730 (patch) | |
tree | 102a01e8b2b8b7df87a912f054f3e62974ba37cb /mpi | |
parent | dfafb4879c1e65657ad89232e57f60c7a07f8c66 (diff) | |
download | txr-22a3cad47355ebbb6aef86b503d98368e8110730.tar.gz txr-22a3cad47355ebbb6aef86b503d98368e8110730.tar.bz2 txr-22a3cad47355ebbb6aef86b503d98368e8110730.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: c30a96120f53b960db56bc05a7ce6310bb2528f5.
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.
Diffstat (limited to 'mpi')
-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); |