Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions base/essentials.jl
Original file line number Diff line number Diff line change
Expand Up @@ -399,8 +399,9 @@ Stacktrace:
[...]
```

If `T` is a [`AbstractFloat`](@ref) type,
then it will return the closest value to `x` representable by `T`.
If `T` is a [`AbstractFloat`](@ref) type, then it will return the
closest value to `x` representable by `T`. Inf is treated as one
ulp greater than `floatmax(T)` for purposes of determining nearest.

```jldoctest
julia> x = 1/3
Expand Down
14 changes: 14 additions & 0 deletions base/float.jl
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,20 @@ round(x::IEEEFloat, ::RoundingMode{:Down}) = floor_llvm(x)
round(x::IEEEFloat, ::RoundingMode{:Up}) = ceil_llvm(x)
round(x::IEEEFloat, ::RoundingMode{:Nearest}) = rint_llvm(x)

rounds_up(x, ::RoundingMode{:Down}) = false
rounds_up(x, ::RoundingMode{:Up}) = true
rounds_up(x, ::RoundingMode{:ToZero}) = x < 0
rounds_up(x, ::RoundingMode{:FromZero}) = x > 0
function round(::Type{T}, x, r::Union{RoundingMode{:ToZero}, RoundingMode{:FromZero}, RoundingMode{:Up}, RoundingMode{:Down}}) where {T<:AbstractFloat}
x_int = round(x, r)
x_t = convert(T, x_int)
if rounds_up(x, r)
x_t < x ? nextfloat(x_t) : x_t
else
x_t > x ? prevfloat(x_t) : x_t
end
end

## floating point promotions ##
promote_rule(::Type{Float32}, ::Type{Float16}) = Float32
promote_rule(::Type{Float64}, ::Type{Float16}) = Float64
Expand Down
10 changes: 10 additions & 0 deletions base/rounding.jl
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,10 @@ The [`RoundingMode`](@ref) `r` controls the direction of the rounding; the defau
of 0.5) being rounded to the nearest even integer. Note that `round` may give incorrect
results if the global rounding mode is changed (see [`rounding`](@ref)).

When rounding to a floating point type, will round to integers representable by that type
(and Inf) rather than true integers. Inf is treated as one ulp greater than the
`floatmax(T)` for purposes of determining "nearest", similar to [`convert`](@ref).

# Examples
```jldoctest
julia> round(1.7)
Expand All @@ -363,6 +367,12 @@ julia> round(123.456; sigdigits=2)

julia> round(357.913; sigdigits=4, base=2)
352.0

julia> round(Float16, typemax(UInt128))
Inf16

julia> floor(Float16, typemax(UInt128))
Float16(6.55e4)
```

!!! note
Expand Down
12 changes: 12 additions & 0 deletions test/rounding.jl
Original file line number Diff line number Diff line change
Expand Up @@ -458,3 +458,15 @@ end
@test_throws InexactError round(Int128, -Inf16)
# More comprehensive testing is present in test/floatfuncs.jl
end

@test "floor(<:AbstractFloat, large_number) (#52355)" begin
@test floor(Float32, 0xffff_ffff) == prevfloat(floatmax(Float32)) <= 0xffff_ffff
@test trunc(Float16, typemax(UInt128)) == floatmax(Float16)
@test round(Float16, typemax(UInt128)) == Inf16
for i in [-BigInt(floatmax(Float64)), -BigInt(floatmax(Float64))*100, BigInt(floatmax(Float64)), BigInt(floatmax(Float64))*100]
f = ceil(Float64, i)
@test f >= i
@test isinteger(f) || isinf(f)
@test prevfloat(f) < i
end
end