Skip to content

Commit

Permalink
Restrict round signature to avoid ambiguities, and add adhoc comparis…
Browse files Browse the repository at this point in the history
…ion for ZZRingElem and Rational{T} (#1558)

* Restrict round signature to avoid ambiguities

* Add adhoc comparision for ZZRingElem and Rational{T}
  • Loading branch information
fingolfin authored Oct 20, 2023
1 parent f2e3115 commit 5778356
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 51 deletions.
2 changes: 2 additions & 0 deletions src/HeckeMiscInteger.jl
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,8 @@ for sym in (:trunc, :round, :ceil, :floor)
# support `trunc(ZZRingElem, 1.23)` etc. for arbitrary reals
Base.$sym(::Type{ZZRingElem}, a::Real) = ZZRingElem(Base.$sym(BigInt, a))
Base.$sym(::Type{ZZRingElem}, a::Rational) = ZZRingElem(Base.$sym(BigInt, a))
Base.$sym(::Type{ZZRingElem}, a::Rational{T}) where T = ZZRingElem(Base.$sym(BigInt, a))
Base.$sym(::Type{ZZRingElem}, a::Rational{Bool}) = ZZRingElem(Base.$sym(BigInt, a))

# for integers we don't need to round in between
Base.$sym(::Type{ZZRingElem}, a::Integer) = ZZRingElem(a)
Expand Down
10 changes: 5 additions & 5 deletions src/flint/fmpq.jl
Original file line number Diff line number Diff line change
Expand Up @@ -190,13 +190,13 @@ Base.trunc(::Type{QQFieldElem}, a::QQFieldElem) = QQFieldElem(trunc(ZZRingElem,
Base.trunc(::Type{ZZRingElem}, a::QQFieldElem) = is_positive(a) ? floor(ZZRingElem, a) : ceil(ZZRingElem, a)

Base.round(x::QQFieldElem, ::RoundingMode{:Up}) = ceil(x)
Base.round(::Type{T}, x::QQFieldElem, ::RoundingMode{:Up}) where T = ceil(T, x)
Base.round(::Type{T}, x::QQFieldElem, ::RoundingMode{:Up}) where T <: RingElement = ceil(T, x)

Base.round(x::QQFieldElem, ::RoundingMode{:Down}) = floor(x)
Base.round(::Type{T}, x::QQFieldElem, ::RoundingMode{:Down}) where T = floor(T, x)
Base.round(::Type{T}, x::QQFieldElem, ::RoundingMode{:Down}) where T <: RingElement = floor(T, x)

Base.round(x::QQFieldElem, ::RoundingMode{:Nearest}) = round(QQFieldElem, x, RoundNearest)
function Base.round(::Type{T}, x::QQFieldElem, ::RoundingMode{:Nearest}) where T
function Base.round(::Type{T}, x::QQFieldElem, ::RoundingMode{:Nearest}) where T <: RingElement
d = denominator(x)
n = numerator(x)
if d == 2
Expand All @@ -219,13 +219,13 @@ function Base.round(::Type{T}, x::QQFieldElem, ::RoundingMode{:Nearest}) where T
end

Base.round(x::QQFieldElem, ::RoundingMode{:NearestTiesAway}) = sign(x) * floor(abs(x) + 1 // 2)
function Base.round(::Type{T}, x::QQFieldElem, ::RoundingMode{:NearestTiesAway}) where T
function Base.round(::Type{T}, x::QQFieldElem, ::RoundingMode{:NearestTiesAway}) where T <: RingElement
tmp = floor(T, abs(x) + 1 // 2)
return is_positive(x) ? tmp : -tmp
end

Base.round(a::QQFieldElem) = round(QQFieldElem, a)
Base.round(::Type{T}, a::QQFieldElem) where T = round(T, a, RoundNearestTiesAway)
Base.round(::Type{T}, a::QQFieldElem) where T <: RingElement = round(T, a, RoundNearestTiesAway)


nbits(a::QQFieldElem) = nbits(numerator(a)) + nbits(denominator(a))
Expand Down
13 changes: 13 additions & 0 deletions src/flint/fmpz.jl
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,19 @@ end

<(x::UInt, y::ZZRingElem) = cmp(y,x) > 0


==(x::ZZRingElem, y::Rational) = isinteger(y) && x == numerator(y)

<=(x::ZZRingElem, y::Rational) = x*denominator(y) <= numerator(y)

<(x::ZZRingElem, y::Rational) = x*denominator(y) < numerator(y)

==(x::Rational, y::ZZRingElem) = isinteger(x) && numerator(x) == y

<=(x::Rational, y::ZZRingElem) = numerator(x) <= y*denominator(x)

<(x::Rational, y::ZZRingElem) = numerator(x) < y*denominator(x)

###############################################################################
#
# Shifting
Expand Down
13 changes: 9 additions & 4 deletions test/flint/fmpq-test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,15 @@ end
@test trunc(QQFieldElem(-1, 3)) == 0
@test trunc(QQFieldElem(2, 1)) == 2

vals = vcat(
Any[d//3 for d in -15:15],
Any[Rational{BigInt}(d//3) for d in -15:15],
Any[Rational{Int16}(d//3) for d in -15:15],
Any[true//true, false//true],
)

@testset "$func" for func in (trunc, round, ceil, floor)
for d in -15:15
val = d//3
for val in vals
valQ = QQFieldElem(val)
@test func(valQ) isa QQFieldElem
@test func(valQ) == func(val)
Expand All @@ -213,8 +219,7 @@ end
end

@testset "$mode" for mode in (RoundUp, RoundDown, RoundNearest, RoundNearestTiesAway)
for d in -5:5
val = d//3
for val in vals
valQ = QQFieldElem(val)
@test round(valQ, mode) isa QQFieldElem
@test round(valQ, mode) == round(val, mode)
Expand Down
95 changes: 53 additions & 42 deletions test/flint/fmpz-test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -530,57 +530,68 @@ end
end

@testset "ZZRingElem.adhoc_comparison" begin
a = ZZRingElem(-12)

@test a < 7

@test a > -40

@test 7 > a

@test -40 < a

@test a <= 7

@test a >= -40

@test 7 >= a

@test -40 <= a

@test a == -12

@test a != 4

@test -12 == a

@test 4 != a

a = ZZRingElem(2)

@test a < UInt(7)

@test a > UInt(1)

@test UInt(7) > a

@test UInt(1) < a
a = ZZRingElem(12)

@test a <= UInt(7)
# values less than a
lt = [-40, UInt(3), 3, 3//1, big(5)//big(3)]

@test a >= UInt(2)
# values equal to a
eq = [12, UInt(12), 12//1, big(12), big(12)//1]

@test UInt(7) >= a
# values greater than a
gt = [40, UInt(40), 40//1, big(40)//big(3)]

@test UInt(1) <= a
@testset "lt $b" for b in lt
@test b < a
@test b <= a
@test !(b > a)
@test !(b >= a)

@test a == UInt(2)
@test !(a < b)
@test !(a <= b)
@test a > b
@test a >= b

@test a != UInt(4)
@test !(a == b)
@test !(b == a)
@test a != b
@test b != a
end

@test UInt(2) == a
@testset "eq $b" for b in eq
@test !(b < a)
@test b <= a
@test !(b > a)
@test b >= a

@test !(a < b)
@test a <= b
@test !(a > b)
@test a >= b

@test a == b
@test b == a
@test !(a != b)
@test !(b != a)
end

@test UInt(4) != a
@testset "gt $b" for b in gt
@test !(b < a)
@test !(b <= a)
@test b > a
@test b >= a

@test a < b
@test a <= b
@test !(a > b)
@test !(a >= b)

@test !(a == b)
@test !(b == a)
@test a != b
@test b != a
end
end

@testset "ZZRingElem.unary_ops" begin
Expand Down

0 comments on commit 5778356

Please sign in to comment.