Skip to content

Commit 17b8fb2

Browse files
authored
add impl
1 parent b0f2661 commit 17b8fb2

File tree

1 file changed

+50
-0
lines changed

1 file changed

+50
-0
lines changed

src

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
export iroot, ispower, rootrem find_exponent, is_probably_prime
2+
3+
module IntegerMathUtils
4+
5+
iroot(x::Integer, n::Integer) = iroot(x, Cint(n))
6+
7+
# TODO: Add more efficient implimentation
8+
iroot(x::T, n::Cint) where {T<:Integer} = T(iroot(big(x), Cint(n)))
9+
10+
function iroot(x::BigInt, n::Cint)
11+
n <= 0 && throw(DomainError(n, "Exponent must be > 0"))
12+
x <= 0 && iseven(x) && throw(DomainError(n, "This is a math no-no"))
13+
ans = BigInt()
14+
ccall((:__gmpz_root, :libgmp), Cint, (Ref{BigInt}, Ref{BigInt}, Cint), ans, x, n)
15+
ans
16+
end
17+
18+
# TODO: Add more efficient implimentation for smaller types
19+
function rootrem(x::T, n::Integer) where {T<:Integer}
20+
x = big(x)
21+
n = Cint(n)
22+
n <= 0 && throw(DomainError(n, "Exponent must be > 0"))
23+
x <= 0 && iseven(x) && throw(DomainError(n, "This is a math no-no"))
24+
root = BigInt()
25+
rem = BigInt()
26+
ccall((:__gmpz_rootrem, :libgmp), Nothing,(Ref{BigInt}, Ref{BigInt}, Ref{BigInt}, Int), root, rem, x, n)
27+
return (root, T(rem))
28+
end
29+
30+
# TODO: Add more efficient implimentation for smaller types
31+
ispower(x::Integer) = ispower(big(x))
32+
33+
function ispower(x::BigInt)
34+
return 0 != ccall((:__gmpz_perfect_power_p, :libgmp), Cint, (Ref{BigInt},), x)
35+
end
36+
37+
# TODO: Add more efficient implimentation for smaller types
38+
function find_exponent(x::Integer)
39+
x <= 1 && return 1
40+
for exponent in ndigits(x, base=2):-1:2
41+
rootrem(x, exponent)[2] == 0 && return exponent
42+
end
43+
1
44+
end
45+
46+
function is_probably_prime(x::Integer; reps=25)
47+
return ccall((:__gmpz_probab_prime_p, :libgmp), Cint, (Ref{BigInt}, Cint), x, reps) != 0
48+
end
49+
50+
end

0 commit comments

Comments
 (0)