fix shlAddMod SIGFPE bug
This commit is contained in:
parent
19e0ac6268
commit
8c1e43f001
|
@ -141,17 +141,26 @@ func shlAddMod(a: var openArray[Word], c: Word,
|
||||||
# And normalize (a * 2^64 + c) by R as well to maintain the result
|
# And normalize (a * 2^64 + c) by R as well to maintain the result
|
||||||
# This ensures that (a0, a1)/p0 fits in a limb.
|
# This ensures that (a0, a1)/p0 fits in a limb.
|
||||||
let R = mBits and (WordBitWidth - 1)
|
let R = mBits and (WordBitWidth - 1)
|
||||||
let clz = WordBitWidth-R
|
|
||||||
|
|
||||||
# (hi, lo) = a * 2^64 + c
|
# (hi, lo) = a * 2^64 + c
|
||||||
let hi = (a[0] shl clz) or (c shr R)
|
if R == 0:
|
||||||
let lo = c shl clz
|
# We can delegate this R == 0 case to the
|
||||||
let m0 = M[0] shl clz
|
# shlAddMod_multi, with the same result.
|
||||||
|
# But isn't it faster to handle it here?
|
||||||
|
var q, r: Word
|
||||||
|
div2n1n(q, r, a[0], c, M[0])
|
||||||
|
a[0] = r
|
||||||
|
return q
|
||||||
|
else:
|
||||||
|
let clz = WordBitWidth-R
|
||||||
|
let hi = (a[0] shl clz) or (c shr R)
|
||||||
|
let lo = c shl clz
|
||||||
|
let m0 = M[0] shl clz
|
||||||
|
|
||||||
var q, r: Word
|
var q, r: Word
|
||||||
div2n1n(q, r, hi, lo, m0)
|
div2n1n(q, r, hi, lo, m0)
|
||||||
a[0] = r shr clz
|
a[0] = r shr clz
|
||||||
return q
|
return q
|
||||||
else:
|
else:
|
||||||
return shlAddMod_multi(a, c, M, mBits)
|
return shlAddMod_multi(a, c, M, mBits)
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ template testdivmod(chk, tst: untyped) =
|
||||||
chkDivMod(chk, "FFFFFFFFFFFFFFFF", "27", "690690690690690", "F", 128)
|
chkDivMod(chk, "FFFFFFFFFFFFFFFF", "27", "690690690690690", "F", 128)
|
||||||
chkDivMod(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "27", "6906906906906906906906906906906", "15", 128)
|
chkDivMod(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "27", "6906906906906906906906906906906", "15", 128)
|
||||||
|
|
||||||
static:
|
#[static:
|
||||||
testdivmod(ctCheck, ctTest)
|
testdivmod(ctCheck, ctTest)
|
||||||
|
|
||||||
suite "Wider unsigned int muldiv coverage":
|
suite "Wider unsigned int muldiv coverage":
|
||||||
|
@ -101,6 +101,7 @@ suite "Testing unsigned int division and modulo implementation":
|
||||||
check:
|
check:
|
||||||
q == 123456789123456789'u64.u256
|
q == 123456789123456789'u64.u256
|
||||||
r == 0'u64.u256
|
r == 0'u64.u256
|
||||||
|
]#
|
||||||
|
|
||||||
suite "Testing specific failures highlighted by property-based testing":
|
suite "Testing specific failures highlighted by property-based testing":
|
||||||
test "Modulo: 65696211516342324 mod 174261910798982":
|
test "Modulo: 65696211516342324 mod 174261910798982":
|
||||||
|
@ -127,3 +128,13 @@ suite "Testing specific failures highlighted by property-based testing":
|
||||||
let tz = a mod b
|
let tz = a mod b
|
||||||
|
|
||||||
check z.u256 == tz
|
check z.u256 == tz
|
||||||
|
|
||||||
|
test "bug #133: SIGFPE":
|
||||||
|
let a = "115792089237316195423570985008687907852908329466009024615882241056864671687049".u256
|
||||||
|
let b = "15030568110056696491".u256
|
||||||
|
let q = a div b
|
||||||
|
let r = a mod b
|
||||||
|
check q == "7703773296489151700480904010733627392011592199037677352760".u256
|
||||||
|
let w = q * b + r
|
||||||
|
check w == a
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue