1
1
module IntegerMathUtils
2
- export iroot, ispower, rootrem, find_exponent, is_probably_prime
2
+ export iroot, ispower, rootrem, find_exponent, is_probably_prime, kronecker
3
3
4
4
iroot (x:: Integer , n:: Integer ) = iroot (x, Cint (n))
5
5
@@ -10,7 +10,7 @@ function iroot(x::BigInt, n::Cint)
10
10
n <= 0 && throw (DomainError (n, " Exponent must be > 0" ))
11
11
x <= 0 && iseven (x) && throw (DomainError (n, " This is a math no-no" ))
12
12
ans = BigInt ()
13
- ccall (( :__gmpz_root , :libgmp ), Cint, ( Ref{BigInt}, Ref{BigInt}, Cint), ans, x, n)
13
+ @ ccall :libgmp . __gmpz_root (ans :: Ref{BigInt} , x :: Ref{BigInt} , n :: Cint ):: Cint
14
14
ans
15
15
end
16
16
@@ -22,15 +22,15 @@ function rootrem(x::T, n::Integer) where {T<:Integer}
22
22
x <= 0 && iseven (x) && throw (DomainError (n, " This is a math no-no" ))
23
23
root = BigInt ()
24
24
rem = BigInt ()
25
- ccall (( :__gmpz_rootrem , :libgmp ), Nothing,( Ref{BigInt}, Ref{BigInt}, Ref{BigInt}, Int), root, rem, x, n)
25
+ @ ccall :libgmp . __gmpz_rootrem (root :: Ref{BigInt} , rem :: Ref{BigInt} , x :: Ref{BigInt} , n :: Int ):: Nothing
26
26
return (root, T (rem))
27
27
end
28
28
29
29
# TODO : Add more efficient implimentation for smaller types
30
30
ispower (x:: Integer ) = ispower (big (x))
31
31
32
32
function ispower (x:: BigInt )
33
- return 0 != ccall (( :__gmpz_perfect_power_p , :libgmp ), Cint, ( Ref{BigInt},), x)
33
+ return 0 != @ ccall :libgmp . __gmpz_perfect_power_p (x :: Ref{BigInt} ) :: Cint
34
34
end
35
35
36
36
# TODO : Add more efficient implimentation for smaller types
@@ -43,7 +43,55 @@ function find_exponent(x::Integer)
43
43
end
44
44
45
45
function is_probably_prime (x:: Integer ; reps= 25 )
46
- return ccall ((:__gmpz_probab_prime_p , :libgmp ), Cint, (Ref{BigInt}, Cint), x, reps) != 0
46
+ if ! (x isa BigInt)
47
+ x = BigInt (x)
48
+ end
49
+ return 0 != @ccall :libgmp . __gmpz_probab_prime_p (x:: Ref{BigInt} , reps:: Cint ):: Cint
50
+ end
51
+
52
+ function kronecker (a:: BigInt , b:: Clong )
53
+ return @ccall :libgmp . __gmpz_kronecker_si (a:: Ref{BigInt} , b:: Clong ):: Cint
54
+ end
55
+ function kronecker (a:: Clong , b:: BigInt )
56
+ return @ccall :libgmp . __gmpz_si_kronecker (a:: Clong , b:: Ref{BigInt} ):: Cint
57
+ end
58
+ function kronecker (a, n)
59
+ @assert n != - n || n == 0
60
+ @assert a != - a || a == 0
61
+ t = 1
62
+ if iszero (n)
63
+ return Int (abs (a) == 1 )
64
+ end
65
+ if n < 0
66
+ n = abs (n)
67
+ if a < 0
68
+ t = - t
69
+ end
70
+ end
71
+ trail = trailing_zeros (n)
72
+ if trail > 0
73
+ n >>= trail
74
+ if iseven (a)
75
+ return 0
76
+ elseif isodd (trail) && a& 7 in (3 ,5 )
77
+ t = - t
78
+ end
79
+ end
80
+ a = mod (a, n)
81
+ while a != 0
82
+ while iseven (a)
83
+ a = a >> 1
84
+ if n& 7 in (3 , 5 )
85
+ t = - t
86
+ end
87
+ end
88
+ a, n = n, a
89
+ if a& 3 == n& 3 == 3
90
+ t = - t
91
+ end
92
+ a = mod (a, n)
93
+ end
94
+ return n == 1 ? t : 0
47
95
end
48
96
49
97
end
0 commit comments