Skip to content

Commit 511837f

Browse files
adienesKristofferC
authored andcommitted
fix overflow in prevfloat with unsigned stepcount (#59668)
fixes #59661 (cherry picked from commit 3b1fa7c)
1 parent c4d2a3a commit 511837f

File tree

2 files changed

+17
-12
lines changed

2 files changed

+17
-12
lines changed

base/float.jl

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -808,13 +808,8 @@ precision(::Type{T}; base::Integer=2) where {T<:AbstractFloat} = _precision(T, b
808808
precision(::T; base::Integer=2) where {T<:AbstractFloat} = precision(T; base)
809809

810810

811-
"""
812-
nextfloat(x::AbstractFloat, n::Integer)
813-
814-
The result of `n` iterative applications of `nextfloat` to `x` if `n >= 0`, or `-n`
815-
applications of [`prevfloat`](@ref) if `n < 0`.
816-
"""
817-
function nextfloat(f::IEEEFloat, d::Integer)
811+
function _nextfloat(f::IEEEFloat, dneg::Bool, da::Integer)
812+
# da must be > 0
818813
F = typeof(f)
819814
fumax = reinterpret(Unsigned, F(Inf))
820815
U = typeof(fumax)
@@ -824,8 +819,6 @@ function nextfloat(f::IEEEFloat, d::Integer)
824819
fneg = fi < 0
825820
fu = unsigned(fi & typemax(fi))
826821

827-
dneg = d < 0
828-
da = uabs(d)
829822
if da > typemax(U)
830823
fneg = dneg
831824
fu = fumax
@@ -852,6 +845,14 @@ function nextfloat(f::IEEEFloat, d::Integer)
852845
reinterpret(F, fu)
853846
end
854847

848+
"""
849+
nextfloat(x::AbstractFloat, n::Integer)
850+
851+
The result of `n` iterative applications of `nextfloat` to `x` if `n >= 0`, or `-n`
852+
applications of [`prevfloat`](@ref) if `n < 0`.
853+
"""
854+
nextfloat(f::AbstractFloat, d::Integer) = _nextfloat(f, isnegative(d), uabs(d))
855+
855856
"""
856857
nextfloat(x::AbstractFloat)
857858
@@ -860,23 +861,23 @@ If no such `y` exists (e.g. if `x` is `Inf` or `NaN`), then return `x`.
860861
861862
See also: [`prevfloat`](@ref), [`eps`](@ref), [`issubnormal`](@ref).
862863
"""
863-
nextfloat(x::AbstractFloat) = nextfloat(x,1)
864+
nextfloat(x::AbstractFloat) = nextfloat(x, 1)
864865

865866
"""
866867
prevfloat(x::AbstractFloat, n::Integer)
867868
868869
The result of `n` iterative applications of `prevfloat` to `x` if `n >= 0`, or `-n`
869870
applications of [`nextfloat`](@ref) if `n < 0`.
870871
"""
871-
prevfloat(x::AbstractFloat, d::Integer) = nextfloat(x, -d)
872+
prevfloat(x::AbstractFloat, d::Integer) = _nextfloat(x, ispositive(d), uabs(d))
872873

873874
"""
874875
prevfloat(x::AbstractFloat)
875876
876877
Return the largest floating point number `y` of the same type as `x` such that `y < x`.
877878
If no such `y` exists (e.g. if `x` is `-Inf` or `NaN`), then return `x`.
878879
"""
879-
prevfloat(x::AbstractFloat) = nextfloat(x,-1)
880+
prevfloat(x::AbstractFloat) = nextfloat(x, -1)
880881

881882
for Ti in (Int8, Int16, Int32, Int64, Int128, UInt8, UInt16, UInt32, UInt64, UInt128)
882883
for Tf in (Float16, Float32, Float64)

test/numbers.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2181,6 +2181,10 @@ end
21812181
@test nextfloat(Inf32) === Inf32
21822182
@test prevfloat(-Inf32) === -Inf32
21832183
@test isequal(nextfloat(NaN32), NaN32)
2184+
@test nextfloat(1.0, UInt(5)) == nextfloat(1.0, 5)
2185+
@test prevfloat(1.0, UInt(5)) == prevfloat(1.0, 5)
2186+
@test nextfloat(0.0, typemax(UInt64)) == Inf
2187+
@test prevfloat(0.0, typemax(UInt64)) == -Inf
21842188
end
21852189
@testset "issue #16206" begin
21862190
@test prevfloat(Inf) == 1.7976931348623157e308

0 commit comments

Comments
 (0)