Skip to content

Commit bead1d3

Browse files
authored
fix spurious overflow for Float16(::Rational) (#52395)
Fixes #52394. Also fixes `Float32` for `UInt128`, since currently `Float32((typemax(UInt128)-0x01) // typemax(UInt128))` gives `Nan32`.
1 parent d765ad1 commit bead1d3

File tree

2 files changed

+13
-0
lines changed

2 files changed

+13
-0
lines changed

base/rational.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,14 @@ function (::Type{T})(x::Rational{S}) where T<:AbstractFloat where S
145145
P = promote_type(T,S)
146146
convert(T, convert(P,x.num)/convert(P,x.den))::T
147147
end
148+
# avoid spurious overflow (#52394). (Needed for UInt16 or larger;
149+
# we also include Int16 for consistency of accuracy.)
150+
Float16(x::Rational{<:Union{Int16,Int32,Int64,UInt16,UInt32,UInt64}}) =
151+
Float16(Float32(x))
152+
Float16(x::Rational{<:Union{Int128,UInt128}}) =
153+
Float16(Float64(x)) # UInt128 overflows Float32, include Int128 for consistency
154+
Float32(x::Rational{<:Union{Int128,UInt128}}) =
155+
Float32(Float64(x)) # UInt128 overflows Float32, include Int128 for consistency
148156

149157
function Rational{T}(x::AbstractFloat) where T<:Integer
150158
r = rationalize(T, x, tol=0)

test/float16.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,11 @@ const minsubf16_32 = Float32(minsubf16)
203203
# issues #33076
204204
@test Float16(1f5) == Inf16
205205

206+
# issue #52394
207+
@test Float16(10^8 // (10^9 + 1)) == convert(Float16, 10^8 // (10^9 + 1)) == Float16(0.1)
208+
@test Float16((typemax(UInt128)-0x01) // typemax(UInt128)) == Float16(1.0)
209+
@test Float32((typemax(UInt128)-0x01) // typemax(UInt128)) == Float32(1.0)
210+
206211
@testset "conversion to Float16 from" begin
207212
for T in (Float32, Float64, BigFloat)
208213
@testset "conversion from $T" begin

0 commit comments

Comments
 (0)