Skip to content

Commit 239d22f

Browse files
committed
avoiding overflow + more tests
1 parent c9bcd85 commit 239d22f

File tree

2 files changed

+55
-5
lines changed

2 files changed

+55
-5
lines changed

Diff for: src/reconstruction/crt.jl

+43-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,44 @@
33
###
44
# CRT
55

6+
# Auxiliary functions allowing to avoid overflow
7+
# on Windows for numbers between 32 and 64 bits
8+
function my_set_ui!(a::BigInt, b::UInt64)
9+
@static if Culong == UInt64
10+
Base.GMP.MPZ.set_ui!(a, b)
11+
else
12+
if b < 2^32
13+
Base.GMP.MPZ.set_ui!(a, b)
14+
else
15+
Base.GMP.MPZ.set!(a, BigInt(b))
16+
end
17+
end
18+
end
19+
20+
function my_mul_ui!(a::BigInt, b::BigInt, c::UInt64)
21+
@static if Culong == UInt64
22+
Base.GMP.MPZ.mul_ui!(a, b, c)
23+
else
24+
if c < 2^32
25+
Base.GMP.MPZ.mul_ui!(a, b, c)
26+
else
27+
Base.GMP.MPZ.mul!(a, b, BigInt(c))
28+
end
29+
end
30+
end
31+
32+
function my_mul_ui!(a::BigInt, b::UInt64)
33+
@static if Culong == UInt64
34+
Base.GMP.MPZ.mul_ui!(a, b)
35+
else
36+
if b < 2^32
37+
Base.GMP.MPZ.mul_ui!(a, b)
38+
else
39+
Base.GMP.MPZ.mul!(a, BigInt(b))
40+
end
41+
end
42+
end
43+
644
"""
745
crt!
846
@@ -23,9 +61,9 @@ Then, `x` is obtained as `x = ∑ ci[i] ai[i] mod M`.
2361
function crt!(M::BigInt, buf::BigInt, n1::BigInt, n2::BigInt, ai::Vector{UInt}, ci::Vector{BigInt})
2462
@invariant length(ai) == length(ci)
2563

26-
Base.GMP.MPZ.set_ui!(n1, UInt(0))
64+
my_set_ui!(n1, UInt(0))
2765
for i in 1:length(ai)
28-
Base.GMP.MPZ.mul_ui!(n2, ci[i], ai[i])
66+
my_mul_ui!(n2, ci[i], ai[i])
2967
Base.GMP.MPZ.add!(n1, n2)
3068
end
3169

@@ -52,13 +90,13 @@ function crt_precompute!(
5290
@invariant length(ci) == length(moduli)
5391

5492
n3, n4 = BigInt(), BigInt()
55-
@inbounds Base.GMP.MPZ.set_ui!(M, moduli[1])
93+
@inbounds my_set_ui!(M, moduli[1])
5694
@inbounds for i in 2:length(moduli)
57-
Base.GMP.MPZ.mul_ui!(M, moduli[i])
95+
my_mul_ui!(M, moduli[i])
5896
end
5997

6098
@inbounds for i in 1:length(moduli)
61-
Base.GMP.MPZ.set_ui!(n2, moduli[i])
99+
my_set_ui!(n2, moduli[i])
62100
Base.GMP.MPZ.tdiv_q!(ci[i], M, n2)
63101
Base.GMP.MPZ.gcdext!(n2, n3, n4, ci[i], n2)
64102
Base.GMP.MPZ.mul!(ci[i], n3)

Diff for: test/crt.jl

+12
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,18 @@
66
Dict(
77
:moduli => Vector{UInt64}([1099511627791, 3518437208889]),
88
:ai => Vector{UInt64}([8590035092, 8589936485])
9+
),
10+
Dict(
11+
:moduli => Vector{UInt64}([1099511627791, 17, 3518437208889]),
12+
:ai => Vector{UInt64}([8590035092, 3, 8589936485])
13+
),
14+
Dict(
15+
:moduli => Vector{UInt64}([1099511627791, 2^30 + 3, 3518437208889]),
16+
:ai => Vector{UInt64}([8590035092, 42, 0])
17+
),
18+
Dict(
19+
:moduli => Vector{UInt64}([1099511627791, 2^30 + 3, 3518437208889]),
20+
:ai => Vector{UInt64}([0, 0, 0])
921
)
1022
)
1123

0 commit comments

Comments
 (0)