-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support rounding Irrational
s
#45598
Support rounding Irrational
s
#45598
Conversation
Hello and thank you for this PR! It looks fine but you should add tests as well, probably in test/numbers.jl. Since these definitions are identical to the ones for Lines 357 to 359 in 56f1d24
which I believe is also more in the spirit of what the docstring of
But I'm not completely sure that's fine either. Tentatively pinging @simonbyrne since I think you're familiar with these, any preference? |
Thank you so much for the quick response! I've added some tests now. I wasn't sure about using |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the tests! Looks good to me.
Since |
I think we may want to extend the type signatures all the way to |
Bump on merging this if it's okay? |
CI failed look unrelated. CI failed list
But it is always helpful to re-run the CI. You can do this by clicking on "Update branch" button. |
I prefer the solution @Liozou proposed of widening the existing type signatures over the approach of adding more methods because it requires less code, leaves fewer special cases, and applies more seamlessly to user-defined types. I think it should be safe to extend these definitions to julia> round(UInt, -5.3)
ERROR: InexactError: trunc(UInt64, -5.0)
Stacktrace:
[1] trunc
@ ./float.jl:760 [inlined]
[2] round(#unused#::Type{UInt64}, x::Float64)
@ Base ./float.jl:359
[3] top-level scope
@ REPL[8]:1 Mathematically, it makes sense to ask for the next highest integer after a real, so I think we should provide generic methods to support this type of query. |
Thanks for the feedback! I've done what you've suggested and extended the already existing signature to |
There's a test failure that indicates an ambiguous method because there are now two definitions. There's a function round(::Type{T}, x::Rational{Tr}, r::RoundingMode=RoundNearest) where {T,Tr}
if iszero(denominator(x))
return convert(T, copysign(unsafe_rational(one(Tr), zero(Tr)), numerator(x)))
end
convert(T, div(numerator(x), denominator(x), r))
end
function round(::Type{T}, x::Rational{Tr}, r::RoundingMode=RoundNearest) where {T<:Integer, Tr}
convert(T, div(numerator(x), denominator(x), r))
end but I'm not an expert so I'd appreciate any help I get 😅 |
Now I see what you meant by
You were quite right! This sounds like a good way to resolve the ambiguity. The second method does not need the |
Ah, the edge cases continue to crop up 😅 this may take time to fix completely. Most of the test failures seem to indicate that there need to be more specific methods defined (either that or there are now ambiguous methods because |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ambiguities between Real and Missing can be fixed by adding
round(::Type{T}, x::Real, r::RoundingMode=RoundNearest) where {T>:Missing} = round(nonmissingtype_checked(T), x, r)
and
($f)(::Type{T}, x::Real) where {T>:Missing} = $f(nonmissingtype_checked(T), x)
methods analogous to the existing methods at base/missing.jl:146 and base/missing.jl:158 to alleviate ambiguities with Rational and Missing.
I think #45598 (comment) is still unresolved |
Whoops yeah, had missed that, resolved now! |
base/float.jl
Outdated
trunc(::Type{T}, x::Real) where {T} = round(T, x, RoundToZero) | ||
floor(::Type{T}, x::Real) where {T} = trunc(T,round(x, RoundDown)) | ||
ceil(::Type{T}, x::Real) where {T} = trunc(T,round(x, RoundUp)) | ||
round(::Type{T}, x::Real) where {T} = trunc(T,round(x, RoundNearest)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should go in floatfuncs.jl by
Lines 153 to 155 in 31d4c22
trunc(x::Real; kwargs...) = round(x, RoundToZero; kwargs...) | |
floor(x::Real; kwargs...) = round(x, RoundDown; kwargs...) | |
ceil(x::Real; kwargs...) = round(x, RoundUp; kwargs...) |
and also pass on keyword arguments.
I also think convert
is more appropriate than trunc
in general. We use trunc
instead of convert
for IEEEFloat
s because it is faster. Perhaps we have these functions dispatch to a three argument round
, have three argument round fallback to convert(T, round(x, rm))
, and define three argument round for floats to use trunc
.
The reason we can't merge as is and make those changes later is that exporting these new generic methods is a feature and changing them would be breaking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey, sorry for dropping the ball on this, I caught up with some things and completely forgot! I think I've implemented these suggestions now. The three argument round
for floats already uses trunc
, I believe:
Lines 122 to 125 in 5e4ecf1
function round(::Type{T}, x::AbstractFloat, r::RoundingMode) where {T<:Integer} | |
r != RoundToZero && (x = round(x,r)) | |
trunc(T, x) | |
end |
so hopefully the current iteration of the code does what was intended 😅
Rounding could probably use some refactoring, but this PR doesn't need to wait for that. |
floor
, ceil
and round
methods (::Type, ::Irrational)
Irrational
s
This reverts commit 881e08b.
From a past triage #50812 (comment)
Which, as I interpret it, means triage agreed with the changes made in this PR. (specifically with widening the type signature to ::Real) So thank you for your contribution, @theabhirath. I think we did the right thing here (or right-ish, nothing is really right or wrong in PL, just lots of opinions) |
Cool, happy to help 😄! (and also to have my first contribution to the base Julia repo 🎉 ) |
Fixes #45588.