mirror of
https://github.com/status-im/nim-stint.git
synced 2025-02-16 17:07:23 +00:00
fix shlAddMod SIGFPE bug
This commit is contained in:
parent
19e0ac6268
commit
8c1e43f001
@ -141,9 +141,18 @@ 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
|
||||||
|
if R == 0:
|
||||||
|
# We can delegate this R == 0 case to the
|
||||||
|
# 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 hi = (a[0] shl clz) or (c shr R)
|
||||||
let lo = c shl clz
|
let lo = c shl clz
|
||||||
let m0 = M[0] shl clz
|
let m0 = M[0] shl clz
|
||||||
|
@ -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…
x
Reference in New Issue
Block a user