summaryrefslogtreecommitdiffstats
path: root/mpi
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-01-18 10:16:28 -0800
committerKaz Kylheku <kaz@kylheku.com>2019-01-18 10:16:28 -0800
commit22a3cad47355ebbb6aef86b503d98368e8110730 (patch)
tree102a01e8b2b8b7df87a912f054f3e62974ba37cb /mpi
parentdfafb4879c1e65657ad89232e57f60c7a07f8c66 (diff)
downloadtxr-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.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/mpi/mpi.c b/mpi/mpi.c
index 472011d4..198a5a86 100644
--- a/mpi/mpi.c
+++ b/mpi/mpi.c
@@ -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);