From 22a3cad47355ebbb6aef86b503d98368e8110730 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 18 Jan 2019 10:16:28 -0800 Subject: 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. --- mpi/mpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'mpi/mpi.c') 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); -- cgit v1.2.3