11module IntegerMathUtils
2- export iroot, ispower, rootrem, find_exponent, is_probably_prime
2+ export iroot, ispower, rootrem, find_exponent, is_probably_prime, kronecker
33
44iroot (x:: Integer , n:: Integer ) = iroot (x, Cint (n))
55
@@ -10,7 +10,7 @@ function iroot(x::BigInt, n::Cint)
1010 n <= 0 && throw (DomainError (n, " Exponent must be > 0" ))
1111 x <= 0 && iseven (x) && throw (DomainError (n, " This is a math no-no" ))
1212 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
1414 ans
1515end
1616
@@ -22,15 +22,15 @@ function rootrem(x::T, n::Integer) where {T<:Integer}
2222 x <= 0 && iseven (x) && throw (DomainError (n, " This is a math no-no" ))
2323 root = BigInt ()
2424 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
2626 return (root, T (rem))
2727end
2828
2929# TODO : Add more efficient implimentation for smaller types
3030ispower (x:: Integer ) = ispower (big (x))
3131
3232function 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
3434end
3535
3636# TODO : Add more efficient implimentation for smaller types
@@ -43,7 +43,55 @@ function find_exponent(x::Integer)
4343end
4444
4545function 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
4795end
4896
4997end
0 commit comments