Skip to content
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

Correct exponent_max to conform to IEEE754-2008 #24978

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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
21 changes: 18 additions & 3 deletions base/math.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,28 @@ end
"Complex(x)^y, or similar.")))
end

"""
exponent_max(T)

Maximum value of [`exponent`](@ref) for a real floating point number of type `T`.
for example 1023 for `Float64`. `exponent_max(T) + 1` is a possible value of
the exponent field with bias, but it is used as sentinel value for `Inf` and `NaN`.
"""
function exponent_max end

"""
exponent_raw_max(T)

The maximum value of the exponent field of floating point type `T` without bias,
that is the maximum integer value representable by `exponent_bits(T)` bits.
"""
function exponent_raw_max end

for T in (Float16, Float32, Float64)
@eval significand_bits(::Type{$T}) = $(trailing_ones(significand_mask(T)))
@eval exponent_bits(::Type{$T}) = $(sizeof(T)*8 - significand_bits(T) - 1)
@eval exponent_bias(::Type{$T}) = $(Int(exponent_one(T) >> significand_bits(T)))
# maximum float exponent
@eval exponent_max(::Type{$T}) = $(Int(exponent_mask(T) >> significand_bits(T)) - exponent_bias(T))
# maximum float exponent without bias
@eval exponent_max(::Type{$T}) = $(Int(exponent_mask(T) >> significand_bits(T)) - exponent_bias(T) - 1)
@eval exponent_raw_max(::Type{$T}) = $(Int(exponent_mask(T) >> significand_bits(T)))
end

Expand Down
2 changes: 1 addition & 1 deletion base/special/exp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ function exp(x::T) where T<:Union{Float32,Float64}
# scale back
if k > -significand_bits(T)
# multiply by 2.0 first to prevent overflow, which helps extends the range
k == exponent_max(T) && return y * T(2.0) * T(2.0)^(exponent_max(T) - 1)
k == exponent_max(T) + 1 && return y * T(2.0) * T(2.0)^exponent_max(T)
twopk = reinterpret(T, rem(exponent_bias(T) + k, uinttype(T)) << significand_bits(T))
return y*twopk
else
Expand Down
2 changes: 1 addition & 1 deletion base/special/exp10.jl
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ function exp10(x::T) where T<:Union{Float32,Float64}
# scale back
if k > -significand_bits(T)
# multiply by 2.0 first to prevent overflow, extending the range
k == exponent_max(T) && return y * T(2.0) * T(2.0)^(exponent_max(T) - 1)
k == exponent_max(T) + 1 && return y * T(2.0) * T(2.0)^exponent_max(T)
twopk = reinterpret(T, rem(exponent_bias(T) + k, uinttype(T)) << significand_bits(T))
return y*twopk
else
Expand Down