Skip to content

Commit

Permalink
Add iroot and check argument for root (#1118)
Browse files Browse the repository at this point in the history
* Add iroot and make root take a check argument.
  • Loading branch information
wbhart authored Jul 30, 2021
1 parent 7314d4a commit eae439b
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 9 deletions.
10 changes: 8 additions & 2 deletions docs/src/integer.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,14 +285,20 @@ isqrtrem(::fmpz)
root(::fmpz, ::Int)
```

```@docs
iroot(::fmpz, ::Int)
```

**Examples**

```julia
a = ZZ(13)
b = ZZ(27)

b = isqrt(a)
c = isqrt(a)
s, r = isqrtrem(a)
c = root(a, 3)
d = iroot(a, 3)
k = root(b, 3; check=true)
```

### Number theoretic functionality
Expand Down
32 changes: 26 additions & 6 deletions src/flint/fmpz.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export fmpz, FlintZZ, FlintIntegerRing, parent, show, convert, hash,
euler_phi, fibonacci, moebius_mu, primorial, rising_factorial,
number_of_partitions, canonical_unit, isunit, isequal, addeq!, mul!,
issquare, square_root, issquare_with_square_root, next_prime,
iszero, rand, rand_bits, binomial, factorial, rand_bits_prime
iszero, rand, rand_bits, binomial, factorial, rand_bits_prime, iroot

###############################################################################
#
Expand Down Expand Up @@ -1132,16 +1132,36 @@ function Base.sqrt(x::fmpz)
end

@doc Markdown.doc"""
root(x::fmpz, n::Int)
root(x::fmpz, n::Int; check::Bool=true)
Return the floor of the $n$-the root of $x$. We require $n > 0$ and that
$x \geq 0$ if $n$ is even.
Return the $n$-the root of $x$. We require $n > 0$ and that
$x \geq 0$ if $n$ is even. By default the function tests whether the input was
a perfect $n$-th power and if not raises an exception. If `check=false` this
check is omitted.
"""
function root(x::fmpz, n::Int)
function root(x::fmpz, n::Int; check::Bool=true)
x < 0 && iseven(n) && throw(DomainError((x, n), "Argument `x` must be positive if exponent `n` is even"))
n <= 0 && throw(DomainError(n, "Exponent must be positive"))
z = fmpz()
ccall((:fmpz_root, libflint), Nothing,
res = ccall((:fmpz_root, libflint), Bool,
(Ref{fmpz}, Ref{fmpz}, Int), z, x, n)
#= Check disabled until flint-2.9 comes out
check && !res && error("Not a perfect n-th power (n = $n)")
=#
return z
end

@doc Markdown.doc"""
iroot(x::fmpz, n::Int)
Return the integer truncation of the $n$-the root of $x$ (round towards zero).
We require $n > 0$ and that $x \geq 0$ if $n$ is even.
"""
function iroot(x::fmpz, n::Int)
x < 0 && iseven(n) && throw(DomainError((x, n), "Argument `x` must be positive if exponent `n` is even"))
n <= 0 && throw(DomainError(n, "Exponent must be positive"))
z = fmpz()
ccall((:fmpz_root, libflint), Bool,
(Ref{fmpz}, Ref{fmpz}, Int), z, x, n)
return z
end
Expand Down
15 changes: 14 additions & 1 deletion test/flint/fmpz-test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -510,10 +510,23 @@ end
@test_throws DomainError isqrtrem(-fmpz(12))

@test root(fmpz(1000), 3) == 10
@test root(-fmpz(27), 3) == -3
@test root(fmpz(27), 3; check=true) == 3

@test_throws DomainError root(-fmpz(1000), 4)

@test_throws DomainError root(fmpz(1000), -3)

#= Disabled until Flint-2.9 comes out
@test_throws ErrorException root(fmpz(1100), 3; check=true)
@test_throws ErrorException root(-fmpz(40), 3; check=true)
=#

@test iroot(fmpz(1000), 3) == 10
@test iroot(fmpz(1100), 3) == 10
@test iroot(-fmpz(40), 3) == -3

@test_throws DomainError iroot(-fmpz(1000), 4)
@test_throws DomainError iroot(fmpz(1000), -3)
end

@testset "fmpz.extended_gcd" begin
Expand Down

0 comments on commit eae439b

Please sign in to comment.