@@ -12,6 +12,10 @@ import .Base: *, +, -, /, <, <<, >>, >>>, <=, ==, >, >=, ^, (~), (&), (|), xor,
12
12
widen, signed, unsafe_trunc, trunc, iszero, isone, big, flipsign, signbit,
13
13
sign, hastypemax
14
14
15
+ Base. @include_stdlib_jll (" GMP_jll" )
16
+ using . GMP_jll
17
+ GMP_jll. __init__ ()
18
+
15
19
if Clong == Int32
16
20
const ClongMax = Union{Int8, Int16, Int32}
17
21
const CulongMax = Union{UInt8, UInt16, UInt32}
21
25
end
22
26
const CdoubleMax = Union{Float16, Float32, Float64}
23
27
24
- version () = VersionNumber (unsafe_string (unsafe_load (cglobal ((:__gmp_version , : libgmp ), Ptr{Cchar}))))
25
- bits_per_limb () = Int (unsafe_load (cglobal ((:__gmp_bits_per_limb , : libgmp ), Cint)))
28
+ version () = VersionNumber (unsafe_string (unsafe_load (cglobal ((:__gmp_version , libgmp), Ptr{Cchar}))))
29
+ bits_per_limb () = Int (unsafe_load (cglobal ((:__gmp_bits_per_limb , libgmp), Cint)))
26
30
27
31
const VERSION = version ()
28
32
const BITS_PER_LIMB = bits_per_limb ()
@@ -54,7 +58,7 @@ mutable struct BigInt <: Signed
54
58
55
59
function BigInt (; nbits:: Integer = 0 )
56
60
b = MPZ. init2! (new (), nbits)
57
- finalizer (cglobal ((:__gmpz_clear , : libgmp )), b)
61
+ finalizer (cglobal ((:__gmpz_clear , libgmp)), b)
58
62
return b
59
63
end
60
64
end
@@ -100,7 +104,7 @@ function __init__()
100
104
" Please rebuild Julia." )
101
105
end
102
106
103
- ccall ((:__gmp_set_memory_functions , : libgmp ), Cvoid,
107
+ ccall ((:__gmp_set_memory_functions , libgmp), Cvoid,
104
108
(Ptr{Cvoid},Ptr{Cvoid},Ptr{Cvoid}),
105
109
cglobal (:jl_gc_counted_malloc ),
106
110
cglobal (:jl_gc_counted_realloc_with_old_size ),
@@ -112,7 +116,7 @@ function __init__()
112
116
end
113
117
# This only works with a patched version of GMP, ignore otherwise
114
118
try
115
- ccall ((:__gmp_set_alloc_overflow_function , : libgmp ), Cvoid,
119
+ ccall ((:__gmp_set_alloc_overflow_function , libgmp), Cvoid,
116
120
(Ptr{Cvoid},),
117
121
cglobal (:jl_throw_out_of_memory_error ))
118
122
ALLOC_OVERFLOW_FUNCTION[] = true
@@ -132,20 +136,20 @@ module MPZ
132
136
# - a method modifying its input has a "!" appendend to its name, according to Julia's conventions
133
137
# - some convenient methods are added (in addition to the pure MPZ ones), e.g. `add(a, b) = add!(BigInt(), a, b)`
134
138
# and `add!(x, a) = add!(x, x, a)`.
135
- using . Base. GMP: BigInt, Limb, BITS_PER_LIMB
139
+ using . Base. GMP: BigInt, Limb, BITS_PER_LIMB, libgmp
136
140
137
141
const mpz_t = Ref{BigInt}
138
142
const bitcnt_t = Culong
139
143
140
- gmpz (op:: Symbol ) = (Symbol (:__gmpz_ , op), : libgmp )
144
+ gmpz (op:: Symbol ) = (Symbol (:__gmpz_ , op), libgmp)
141
145
142
- init! (x:: BigInt ) = (ccall ((:__gmpz_init , : libgmp ), Cvoid, (mpz_t,), x); x)
143
- init2! (x:: BigInt , a) = (ccall ((:__gmpz_init2 , : libgmp ), Cvoid, (mpz_t, bitcnt_t), x, a); x)
146
+ init! (x:: BigInt ) = (ccall ((:__gmpz_init , libgmp), Cvoid, (mpz_t,), x); x)
147
+ init2! (x:: BigInt , a) = (ccall ((:__gmpz_init2 , libgmp), Cvoid, (mpz_t, bitcnt_t), x, a); x)
144
148
145
- realloc2! (x, a) = (ccall ((:__gmpz_realloc2 , : libgmp ), Cvoid, (mpz_t, bitcnt_t), x, a); x)
149
+ realloc2! (x, a) = (ccall ((:__gmpz_realloc2 , libgmp), Cvoid, (mpz_t, bitcnt_t), x, a); x)
146
150
realloc2 (a) = realloc2! (BigInt (), a)
147
151
148
- sizeinbase (a:: BigInt , b) = Int (ccall ((:__gmpz_sizeinbase , : libgmp ), Csize_t, (mpz_t, Cint), a, b))
152
+ sizeinbase (a:: BigInt , b) = Int (ccall ((:__gmpz_sizeinbase , libgmp), Csize_t, (mpz_t, Cint), a, b))
149
153
150
154
for (op, nbits) in (:add => :(BITS_PER_LIMB* (1 + max (abs (a. size), abs (b. size)))),
151
155
:sub => :(BITS_PER_LIMB* (1 + max (abs (a. size), abs (b. size)))),
@@ -161,7 +165,7 @@ for (op, nbits) in (:add => :(BITS_PER_LIMB*(1 + max(abs(a.size), abs(b.size))))
161
165
end
162
166
163
167
invert! (x:: BigInt , a:: BigInt , b:: BigInt ) =
164
- ccall ((:__gmpz_invert , : libgmp ), Cint, (mpz_t, mpz_t, mpz_t), x, a, b)
168
+ ccall ((:__gmpz_invert , libgmp), Cint, (mpz_t, mpz_t, mpz_t), x, a, b)
165
169
invert (a:: BigInt , b:: BigInt ) = invert! (BigInt (), a, b)
166
170
invert! (x:: BigInt , b:: BigInt ) = invert! (x, x, b)
167
171
@@ -174,14 +178,14 @@ for op in (:add_ui, :sub_ui, :mul_ui, :mul_2exp, :fdiv_q_2exp, :pow_ui, :bin_ui)
174
178
end
175
179
end
176
180
177
- ui_sub! (x:: BigInt , a, b:: BigInt ) = (ccall ((:__gmpz_ui_sub , : libgmp ), Cvoid, (mpz_t, Culong, mpz_t), x, a, b); x)
181
+ ui_sub! (x:: BigInt , a, b:: BigInt ) = (ccall ((:__gmpz_ui_sub , libgmp), Cvoid, (mpz_t, Culong, mpz_t), x, a, b); x)
178
182
ui_sub (a, b:: BigInt ) = ui_sub! (BigInt (), a, b)
179
183
180
184
for op in (:scan1 , :scan0 )
181
185
@eval $ op (a:: BigInt , b) = Int (ccall ($ (gmpz (op)), Culong, (mpz_t, Culong), a, b))
182
186
end
183
187
184
- mul_si! (x:: BigInt , a:: BigInt , b) = (ccall ((:__gmpz_mul_si , : libgmp ), Cvoid, (mpz_t, mpz_t, Clong), x, a, b); x)
188
+ mul_si! (x:: BigInt , a:: BigInt , b) = (ccall ((:__gmpz_mul_si , libgmp), Cvoid, (mpz_t, mpz_t, Clong), x, a, b); x)
185
189
mul_si (a:: BigInt , b) = mul_si! (BigInt (), a, b)
186
190
mul_si! (x:: BigInt , b) = mul_si! (x, x, b)
187
191
@@ -203,47 +207,47 @@ for (op, T) in ((:fac_ui, Culong), (:set_ui, Culong), (:set_si, Clong), (:set_d,
203
207
end
204
208
end
205
209
206
- popcount (a:: BigInt ) = Int (ccall ((:__gmpz_popcount , : libgmp ), Culong, (mpz_t,), a))
210
+ popcount (a:: BigInt ) = Int (ccall ((:__gmpz_popcount , libgmp), Culong, (mpz_t,), a))
207
211
208
- mpn_popcount (d:: Ptr{Limb} , s:: Integer ) = Int (ccall ((:__gmpn_popcount , : libgmp ), Culong, (Ptr{Limb}, Csize_t), d, s))
212
+ mpn_popcount (d:: Ptr{Limb} , s:: Integer ) = Int (ccall ((:__gmpn_popcount , libgmp), Culong, (Ptr{Limb}, Csize_t), d, s))
209
213
mpn_popcount (a:: BigInt ) = mpn_popcount (a. d, abs (a. size))
210
214
211
215
function tdiv_qr! (x:: BigInt , y:: BigInt , a:: BigInt , b:: BigInt )
212
- ccall ((:__gmpz_tdiv_qr , : libgmp ), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t), x, y, a, b)
216
+ ccall ((:__gmpz_tdiv_qr , libgmp), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t), x, y, a, b)
213
217
x, y
214
218
end
215
219
tdiv_qr (a:: BigInt , b:: BigInt ) = tdiv_qr! (BigInt (), BigInt (), a, b)
216
220
217
221
powm! (x:: BigInt , a:: BigInt , b:: BigInt , c:: BigInt ) =
218
- (ccall ((:__gmpz_powm , : libgmp ), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t), x, a, b, c); x)
222
+ (ccall ((:__gmpz_powm , libgmp), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t), x, a, b, c); x)
219
223
powm (a:: BigInt , b:: BigInt , c:: BigInt ) = powm! (BigInt (), a, b, c)
220
224
powm! (x:: BigInt , b:: BigInt , c:: BigInt ) = powm! (x, x, b, c)
221
225
222
226
function gcdext! (x:: BigInt , y:: BigInt , z:: BigInt , a:: BigInt , b:: BigInt )
223
- ccall ((:__gmpz_gcdext , : libgmp ), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t, mpz_t), x, y, z, a, b)
227
+ ccall ((:__gmpz_gcdext , libgmp), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t, mpz_t), x, y, z, a, b)
224
228
x, y, z
225
229
end
226
230
gcdext (a:: BigInt , b:: BigInt ) = gcdext! (BigInt (), BigInt (), BigInt (), a, b)
227
231
228
- cmp (a:: BigInt , b:: BigInt ) = Int (ccall ((:__gmpz_cmp , : libgmp ), Cint, (mpz_t, mpz_t), a, b))
229
- cmp_si (a:: BigInt , b) = Int (ccall ((:__gmpz_cmp_si , : libgmp ), Cint, (mpz_t, Clong), a, b))
230
- cmp_ui (a:: BigInt , b) = Int (ccall ((:__gmpz_cmp_ui , : libgmp ), Cint, (mpz_t, Culong), a, b))
231
- cmp_d (a:: BigInt , b) = Int (ccall ((:__gmpz_cmp_d , : libgmp ), Cint, (mpz_t, Cdouble), a, b))
232
+ cmp (a:: BigInt , b:: BigInt ) = Int (ccall ((:__gmpz_cmp , libgmp), Cint, (mpz_t, mpz_t), a, b))
233
+ cmp_si (a:: BigInt , b) = Int (ccall ((:__gmpz_cmp_si , libgmp), Cint, (mpz_t, Clong), a, b))
234
+ cmp_ui (a:: BigInt , b) = Int (ccall ((:__gmpz_cmp_ui , libgmp), Cint, (mpz_t, Culong), a, b))
235
+ cmp_d (a:: BigInt , b) = Int (ccall ((:__gmpz_cmp_d , libgmp), Cint, (mpz_t, Cdouble), a, b))
232
236
233
- mpn_cmp (a:: Ptr{Limb} , b:: Ptr{Limb} , c) = ccall ((:__gmpn_cmp , : libgmp ), Cint, (Ptr{Limb}, Ptr{Limb}, Clong), a, b, c)
237
+ mpn_cmp (a:: Ptr{Limb} , b:: Ptr{Limb} , c) = ccall ((:__gmpn_cmp , libgmp), Cint, (Ptr{Limb}, Ptr{Limb}, Clong), a, b, c)
234
238
mpn_cmp (a:: BigInt , b:: BigInt , c) = mpn_cmp (a. d, b. d, c)
235
239
236
- get_str! (x, a, b:: BigInt ) = (ccall ((:__gmpz_get_str ,: libgmp ), Ptr{Cchar}, (Ptr{Cchar}, Cint, mpz_t), x, a, b); x)
237
- set_str! (x:: BigInt , a, b) = Int (ccall ((:__gmpz_set_str , : libgmp ), Cint, (mpz_t, Ptr{UInt8}, Cint), x, a, b))
238
- get_d (a:: BigInt ) = ccall ((:__gmpz_get_d , : libgmp ), Cdouble, (mpz_t,), a)
240
+ get_str! (x, a, b:: BigInt ) = (ccall ((:__gmpz_get_str ,libgmp), Ptr{Cchar}, (Ptr{Cchar}, Cint, mpz_t), x, a, b); x)
241
+ set_str! (x:: BigInt , a, b) = Int (ccall ((:__gmpz_set_str , libgmp), Cint, (mpz_t, Ptr{UInt8}, Cint), x, a, b))
242
+ get_d (a:: BigInt ) = ccall ((:__gmpz_get_d , libgmp), Cdouble, (mpz_t,), a)
239
243
240
- limbs_write! (x:: BigInt , a) = ccall ((:__gmpz_limbs_write , : libgmp ), Ptr{Limb}, (mpz_t, Clong), x, a)
241
- limbs_finish! (x:: BigInt , a) = ccall ((:__gmpz_limbs_finish , : libgmp ), Cvoid, (mpz_t, Clong), x, a)
242
- import! (x:: BigInt , a, b, c, d, e, f) = ccall ((:__gmpz_import , : libgmp ), Cvoid,
244
+ limbs_write! (x:: BigInt , a) = ccall ((:__gmpz_limbs_write , libgmp), Ptr{Limb}, (mpz_t, Clong), x, a)
245
+ limbs_finish! (x:: BigInt , a) = ccall ((:__gmpz_limbs_finish , libgmp), Cvoid, (mpz_t, Clong), x, a)
246
+ import! (x:: BigInt , a, b, c, d, e, f) = ccall ((:__gmpz_import , libgmp), Cvoid,
243
247
(mpz_t, Csize_t, Cint, Csize_t, Cint, Csize_t, Ptr{Cvoid}), x, a, b, c, d, e, f)
244
248
245
- setbit! (x, a) = (ccall ((:__gmpz_setbit , : libgmp ), Cvoid, (mpz_t, bitcnt_t), x, a); x)
246
- tstbit (a:: BigInt , b) = ccall ((:__gmpz_tstbit , : libgmp ), Cint, (mpz_t, bitcnt_t), a, b) % Bool
249
+ setbit! (x, a) = (ccall ((:__gmpz_setbit , libgmp), Cvoid, (mpz_t, bitcnt_t), x, a); x)
250
+ tstbit (a:: BigInt , b) = ccall ((:__gmpz_tstbit , libgmp), Cint, (mpz_t, bitcnt_t), a, b) % Bool
247
251
248
252
end # module MPZ
249
253
0 commit comments