From 881e08bcff7fad1a662d07f0b5b13ba3d6fd2581 Mon Sep 17 00:00:00 2001 From: Abhirath Anand <74202102+theabhirath@users.noreply.github.com> Date: Thu, 3 Aug 2023 21:20:41 +0530 Subject: [PATCH] Support rounding `Irrational`s (#45598) --- base/float.jl | 5 ----- base/floatfuncs.jl | 8 ++++++++ base/missing.jl | 2 ++ base/rational.jl | 4 ---- test/numbers.jl | 11 +++++++++++ 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/base/float.jl b/base/float.jl index fc4cef09b48ad..3a17d517bbb89 100644 --- a/base/float.jl +++ b/base/float.jl @@ -379,11 +379,6 @@ trunc(::Type{Signed}, x::IEEEFloat) = trunc(Int,x) trunc(::Type{Unsigned}, x::IEEEFloat) = trunc(UInt,x) trunc(::Type{Integer}, x::IEEEFloat) = trunc(Int,x) -# fallbacks -floor(::Type{T}, x::AbstractFloat) where {T<:Integer} = trunc(T,round(x, RoundDown)) -ceil(::Type{T}, x::AbstractFloat) where {T<:Integer} = trunc(T,round(x, RoundUp)) -round(::Type{T}, x::AbstractFloat) where {T<:Integer} = trunc(T,round(x, RoundNearest)) - # Bool trunc(::Type{Bool}, x::AbstractFloat) = (-1 < x < 2) ? 1 <= x : throw(InexactError(:trunc, Bool, x)) floor(::Type{Bool}, x::AbstractFloat) = (0 <= x < 2) ? 1 <= x : throw(InexactError(:floor, Bool, x)) diff --git a/base/floatfuncs.jl b/base/floatfuncs.jl index 9b8ca4b04ee28..0dde9431ee968 100644 --- a/base/floatfuncs.jl +++ b/base/floatfuncs.jl @@ -154,6 +154,14 @@ trunc(x::Real; kwargs...) = round(x, RoundToZero; kwargs...) floor(x::Real; kwargs...) = round(x, RoundDown; kwargs...) ceil(x::Real; kwargs...) = round(x, RoundUp; kwargs...) +# fallbacks +trunc(::Type{T}, x::Real; kwargs...) where {T} = round(T, x, RoundToZero; kwargs...) +floor(::Type{T}, x::Real; kwargs...) where {T} = round(T, x, RoundDown; kwargs...) +ceil(::Type{T}, x::Real; kwargs...) where {T} = round(T, x, RoundUp; kwargs...) +round(::Type{T}, x::Real; kwargs...) where {T} = round(T, x, RoundNearest; kwargs...) + +round(::Type{T}, x::Real, r::RoundingMode) where {T} = convert(T, round(x, r)) + round(x::Integer, r::RoundingMode) = x # round x to multiples of 1/invstep diff --git a/base/missing.jl b/base/missing.jl index f6f5fe507260b..f0cad70690ebe 100644 --- a/base/missing.jl +++ b/base/missing.jl @@ -146,6 +146,7 @@ round(::Type{T}, ::Missing, ::RoundingMode=RoundNearest) where {T} = throw(MissingException(missing_conversion_msg(T))) round(::Type{T}, x::Any, r::RoundingMode=RoundNearest) where {T>:Missing} = round(nonmissingtype_checked(T), x, r) # to fix ambiguities +round(::Type{T}, x::Real, r::RoundingMode=RoundNearest) where {T>:Missing} = round(nonmissingtype_checked(T), x, r) round(::Type{T}, x::Rational{Tr}, r::RoundingMode=RoundNearest) where {T>:Missing,Tr} = round(nonmissingtype_checked(T), x, r) round(::Type{T}, x::Rational{Bool}, r::RoundingMode=RoundNearest) where {T>:Missing} = round(nonmissingtype_checked(T), x, r) @@ -158,6 +159,7 @@ for f in (:(ceil), :(floor), :(trunc)) ($f)(::Type{T}, x::Any) where {T>:Missing} = $f(nonmissingtype_checked(T), x) # to fix ambiguities ($f)(::Type{T}, x::Rational) where {T>:Missing} = $f(nonmissingtype_checked(T), x) + ($f)(::Type{T}, x::Real) where {T>:Missing} = $f(nonmissingtype_checked(T), x) end end diff --git a/base/rational.jl b/base/rational.jl index 5b9ff99ea7a6c..cfa1e257bc539 100644 --- a/base/rational.jl +++ b/base/rational.jl @@ -484,10 +484,6 @@ for (S, T) in ((Rational, Integer), (Integer, Rational), (Rational, Rational)) end end -trunc(::Type{T}, x::Rational) where {T} = round(T, x, RoundToZero) -floor(::Type{T}, x::Rational) where {T} = round(T, x, RoundDown) -ceil(::Type{T}, x::Rational) where {T} = round(T, x, RoundUp) - round(x::Rational, r::RoundingMode=RoundNearest) = round(typeof(x), x, r) function round(::Type{T}, x::Rational{Tr}, r::RoundingMode=RoundNearest) where {T,Tr} diff --git a/test/numbers.jl b/test/numbers.jl index e89dffd8e33cf..a1b425c6d8f19 100644 --- a/test/numbers.jl +++ b/test/numbers.jl @@ -1168,6 +1168,17 @@ Base.@irrational i46051 4863.185427757 1548big(pi) # issue #46051 @test sprint(show, "text/plain", i46051) == "i46051 = 4863.185427757..." end + +@testset "Irrational round, float, ceil" begin + using .MathConstants + @test round(π) === 3.0 + @test round(Int, ℯ) === 3 + @test floor(ℯ) === 2.0 + @test floor(Int, φ) === 1 + @test ceil(γ) === 1.0 + @test ceil(Int, catalan) === 1 +end + @testset "issue #6365" begin for T in (Float32, Float64) for i = 9007199254740992:9007199254740996