nimvm bug workaround
This commit is contained in:
parent
ddcb2111e4
commit
21eeee72df
|
@ -113,13 +113,6 @@ func mulmod*(a, b, m: StUint): StUint =
|
||||||
func powmod*(a, b, m: StUint): StUint =
|
func powmod*(a, b, m: StUint): StUint =
|
||||||
## Modular exponentiation
|
## Modular exponentiation
|
||||||
|
|
||||||
when nimvm:
|
|
||||||
doAssert false, "cannot use powmod at compile-time"
|
|
||||||
else:
|
|
||||||
# we need this ugly branch
|
|
||||||
# because of nim-lang/Nim#12517
|
|
||||||
discard
|
|
||||||
|
|
||||||
let a_m = if a < m: a
|
let a_m = if a < m: a
|
||||||
else: a mod m
|
else: a mod m
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ func shlAddMod_multi(a: var openArray[Word], c: Word,
|
||||||
M: openArray[Word], mBits: int): Word =
|
M: openArray[Word], mBits: int): Word =
|
||||||
## Fused modular left-shift + add
|
## Fused modular left-shift + add
|
||||||
## Shift input `a` by a word and add `c` modulo `M`
|
## Shift input `a` by a word and add `c` modulo `M`
|
||||||
##
|
##
|
||||||
## Specialized for M being a multi-precision integer.
|
## Specialized for M being a multi-precision integer.
|
||||||
##
|
##
|
||||||
## With a word W = 2^WordBitWidth and a modulus M
|
## With a word W = 2^WordBitWidth and a modulus M
|
||||||
|
@ -55,7 +55,7 @@ func shlAddMod_multi(a: var openArray[Word], c: Word,
|
||||||
## and returns q = (a * W + c ) / M
|
## and returns q = (a * W + c ) / M
|
||||||
##
|
##
|
||||||
## The modulus `M` most-significant bit at `mBits` MUST be set.
|
## The modulus `M` most-significant bit at `mBits` MUST be set.
|
||||||
|
|
||||||
# Assuming 64-bit words
|
# Assuming 64-bit words
|
||||||
let hi = a[^1] # Save the high word to detect carries
|
let hi = a[^1] # Save the high word to detect carries
|
||||||
let R = mBits and (WordBitWidth - 1) # R = mBits mod 64
|
let R = mBits and (WordBitWidth - 1) # R = mBits mod 64
|
||||||
|
@ -128,7 +128,7 @@ func shlAddMod(a: var openArray[Word], c: Word,
|
||||||
M: openArray[Word], mBits: int): Word {.inline.}=
|
M: openArray[Word], mBits: int): Word {.inline.}=
|
||||||
## Fused modular left-shift + add
|
## Fused modular left-shift + add
|
||||||
## Shift input `a` by a word and add `c` modulo `M`
|
## Shift input `a` by a word and add `c` modulo `M`
|
||||||
##
|
##
|
||||||
## With a word W = 2^WordBitWidth and a modulus M
|
## With a word W = 2^WordBitWidth and a modulus M
|
||||||
## Does a <- a * W + c (mod M)
|
## Does a <- a * W + c (mod M)
|
||||||
## and returns q = (a * W + c ) / M
|
## and returns q = (a * W + c ) / M
|
||||||
|
@ -182,13 +182,28 @@ func divRem*(
|
||||||
copyWords(r, 0, a, aOffset+1, bLen-1)
|
copyWords(r, 0, a, aOffset+1, bLen-1)
|
||||||
r[rLen-1] = 0
|
r[rLen-1] = 0
|
||||||
# Now shift-left the copied words while adding the new word mod b
|
# Now shift-left the copied words while adding the new word mod b
|
||||||
for i in countdown(aOffset, 0):
|
|
||||||
q[i] = shlAddMod(
|
when nimvm:
|
||||||
r.toOpenArray(0, rLen-1),
|
# workaround nim bug #22095
|
||||||
a[i],
|
var rr = @(r.toOpenArray(0, rLen-1))
|
||||||
b.toOpenArray(0, bLen-1),
|
var bb = @(b.toOpenArray(0, bLen-1))
|
||||||
bBits
|
for i in countdown(aOffset, 0):
|
||||||
)
|
q[i] = shlAddMod(
|
||||||
|
rr,
|
||||||
|
a[i],
|
||||||
|
bb,
|
||||||
|
bBits
|
||||||
|
)
|
||||||
|
for i in 0..rLen-1:
|
||||||
|
r[i] = rr[i]
|
||||||
|
else:
|
||||||
|
for i in countdown(aOffset, 0):
|
||||||
|
q[i] = shlAddMod(
|
||||||
|
r.toOpenArray(0, rLen-1),
|
||||||
|
a[i],
|
||||||
|
b.toOpenArray(0, bLen-1),
|
||||||
|
bBits
|
||||||
|
)
|
||||||
|
|
||||||
# Clean up extra words
|
# Clean up extra words
|
||||||
for i in aOffset+1 ..< q.len:
|
for i in aOffset+1 ..< q.len:
|
||||||
|
@ -229,7 +244,7 @@ func divRem*(
|
||||||
# - An Efficient Multiple-Precision Division Algorithm,
|
# - An Efficient Multiple-Precision Division Algorithm,
|
||||||
# Liusheng Huang, Hong Zhong, Hong Shen, Yonglong Luo, 2005
|
# Liusheng Huang, Hong Zhong, Hong Shen, Yonglong Luo, 2005
|
||||||
# https://ieeexplore.ieee.org/document/1579076
|
# https://ieeexplore.ieee.org/document/1579076
|
||||||
#
|
#
|
||||||
# - Efficient multiple-precision integer division algorithm
|
# - Efficient multiple-precision integer division algorithm
|
||||||
# Debapriyay Mukhopadhyaya, Subhas C.Nandy, 2014
|
# Debapriyay Mukhopadhyaya, Subhas C.Nandy, 2014
|
||||||
# https://www.sciencedirect.com/science/article/abs/pii/S0020019013002627
|
# https://www.sciencedirect.com/science/article/abs/pii/S0020019013002627
|
||||||
|
|
|
@ -116,8 +116,8 @@ template testMuldiv(chk, tst: untyped) =
|
||||||
chkMod(chk, 2, -5, 2, 64)
|
chkMod(chk, 2, -5, 2, 64)
|
||||||
chkMod(chk, -2, -5, -2, 64)
|
chkMod(chk, -2, -5, -2, 64)
|
||||||
|
|
||||||
#static:
|
static:
|
||||||
#testMuldiv(ctCheck, ctTest)
|
testMuldiv(ctCheck, ctTest)
|
||||||
|
|
||||||
suite "Wider signed int muldiv coverage":
|
suite "Wider signed int muldiv coverage":
|
||||||
testMuldiv(check, test)
|
testMuldiv(check, test)
|
||||||
|
|
|
@ -60,8 +60,8 @@ 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":
|
||||||
testdivmod(check, test)
|
testdivmod(check, test)
|
||||||
|
|
|
@ -56,8 +56,8 @@ template testModArith(chk, tst: untyped) =
|
||||||
chkPowMod(chk, "FFFFFFFFFFFFFFFF", "3", "C", "3", 128)
|
chkPowMod(chk, "FFFFFFFFFFFFFFFF", "3", "C", "3", 128)
|
||||||
chkPowMod(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "3", "C", "3", 128)
|
chkPowMod(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "3", "C", "3", 128)
|
||||||
|
|
||||||
#static:
|
static:
|
||||||
#testModArith(ctCheck, ctTest)
|
testModArith(ctCheck, ctTest)
|
||||||
|
|
||||||
suite "Wider unsigned Modular arithmetic coverage":
|
suite "Wider unsigned Modular arithmetic coverage":
|
||||||
testModArith(check, test)
|
testModArith(check, test)
|
||||||
|
|
Loading…
Reference in New Issue