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

exp of some NaNs is negative #56782

Closed
aplavin opened this issue Dec 9, 2024 · 4 comments · Fixed by #56784
Closed

exp of some NaNs is negative #56782

aplavin opened this issue Dec 9, 2024 · 4 comments · Fixed by #56784
Assignees
Labels
bug Indicates an unexpected problem or unintended behavior maths Mathematical functions

Comments

@aplavin
Copy link
Contributor

aplavin commented Dec 9, 2024

Presumably, negative exp should never happen, and this should return a NaN instead?

julia> reinterpret(Float64, 0x7ffbb14880000000)
NaN

julia> exp(reinterpret(Float64, 0x7ffbb14880000000))
-9.627794635514914e-309
@KristofferC KristofferC added bug Indicates an unexpected problem or unintended behavior maths Mathematical functions labels Dec 9, 2024
@oscardssmith
Copy link
Member

yeah, this is bad.

@inkydragon
Copy link
Member

inkydragon commented Dec 10, 2024

And more...

julia> wNaN = reinterpret(Float64, 0x7ffbb14880000000)
NaN

julia> bad_func = [cosh, sinh, tanh, exp, exp10, exp2]
6-element Vector{Function}:
 cosh (generic function with 12 methods)
 sinh (generic function with 12 methods)
 tanh (generic function with 12 methods)
 exp (generic function with 13 methods)
 exp10 (generic function with 7 methods)
 exp2 (generic function with 8 methods)

julia> [ f(wNaN) for f in bad_func ]
6-element Vector{Float64}:
 -5.193297311884955e307
  5.193297311884955e307
  1.0
 -9.627794635514914e-309
 -9.627794635514914e-309
 -9.627794635514914e-309
Test script
c23_libm_unary = [
    #= F.10.1 Trigonometric functions =#
        acos, asin, atan,
        cos, sin, tan,
        # acospi, asinpi, atanpi,  # not-impl
        cospi, sinpi, tanpi,
    #= F.10.2 Hyperbolic functions =#
        acosh, asinh, atanh,
        cosh, sinh, tanh,
    #= F.10.3 Exponential and logarithmic functions =#
        exp, exp10,
        # exp10m1,
        exp2,
        # exp2m1,
        expm1,
        # frexp,  # NOTE: ldexp(x, n), test as unary
        f->ldexp(f, 1),
        # modf  # NOTE: ret (x,exp)
        f->modf(f)[1],
        f->modf(f)[2],
        # ilogb,
        log, log10,
        # log10p1, logp1, 
        log2,
        # log2p1, logb,
    #= F.10.4 Power and absolute value functions =#
        cbrt,
        abs, # (fabs)
        # rsqrt,
        sqrt,
    #= F.10.5 Error and gamma functions =#
        # erf, erfc, lgamma, tgamma,
    #= F.10.6 Nearest integer functions =#
        ceil, floor,
        # nearbyint, rint,
        round,
        # roundeven,
        trunc,
]

c23_libm_binary = [
    #= F.10.1 Trigonometric functions =#
        # atan2, atan2pi,  # not-impl
    #= F.10.2 Hyperbolic functions (no binary func) =#
    #= F.10.3 Exponential and logarithmic functions =#
        # ldexp,  # NOTE: test as unary
        # scalbn,
    #= F.10.4 Power and absolute value functions =#
        # compoundn,
        hypot,
        ^, # (pow, pown, powr,)
        # rootn,
    #= F.10.5 Error and gamma functions (no binary func) =#
    #= F.10.6 Nearest integer functions (no binary func) =#
    #= F.10.7 Remainder functions =#
        mod,  # (fmod)
        rem,  # (remainder)
        # remquo,
]

wNaN16 = reinterpret(Float16, reinterpret(UInt16, NaN16)+0x4)
wNaN32 = reinterpret(Float32, reinterpret(UInt32, NaN32)+0x8)
wNaN64 = reinterpret(Float64, 0x7ffbb14880000000)

@info "Test c23_libm_unary($(length(c23_libm_unary)))"
[ isnan(f(NaN)) for f in c23_libm_unary] |> all
[ isnan(f(wNaN16)) for f in c23_libm_unary] |> all
[ isnan(f(wNaN32)) for f in c23_libm_unary] |> all
[ isnan(f(wNaN64)) for f in c23_libm_unary] |> all
for f in c23_libm_unary
    isnan(f(wNaN64)) || println(f)
end

@info "Test c23_libm_binary($(length(c23_libm_binary)))"
[ isnan(f2(NaN,NaN)) for f2 in c23_libm_binary] |> all
[ isnan(f2(wNaN16,NaN)) for f2 in c23_libm_binary] |> all
[ isnan(f2(wNaN32,NaN)) for f2 in c23_libm_binary] |> all
[ isnan(f2(wNaN64,NaN)) for f2 in c23_libm_binary] |> all
for f2 in c23_libm_binary
    isnan(f2(wNaN64, NaN)) || println(f)
    isnan(f2(NaN, wNaN64)) || println(f)
    isnan(f2(wNaN64, wNaN64)) || println(f)
end

@oscardssmith
Copy link
Member

all of those are fixed by my pr, right?

@inkydragon
Copy link
Member

all of those are fixed by my pr, right?

I guess so, since all those functions are related to exp.

KristofferC pushed a commit that referenced this issue Dec 13, 2024
Fixes #56782
Fix `exp(reinterpret(Float64, 0x7ffbb14880000000))` returning non-NaN
value. This should have minimal performance impact since it's already in
the fallback branch.

(cherry picked from commit 19e06d3)
KristofferC pushed a commit that referenced this issue Dec 13, 2024
Fixes #56782
Fix `exp(reinterpret(Float64, 0x7ffbb14880000000))` returning non-NaN
value. This should have minimal performance impact since it's already in
the fallback branch.

(cherry picked from commit 19e06d3)
stevengj pushed a commit that referenced this issue Jan 2, 2025
Fixes #56782
Fix `exp(reinterpret(Float64, 0x7ffbb14880000000))` returning non-NaN
value. This should have minimal performance impact since it's already in
the fallback branch.
KristofferC pushed a commit that referenced this issue Jan 13, 2025
Fixes #56782
Fix `exp(reinterpret(Float64, 0x7ffbb14880000000))` returning non-NaN
value. This should have minimal performance impact since it's already in
the fallback branch.

(cherry picked from commit 19e06d3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Indicates an unexpected problem or unintended behavior maths Mathematical functions
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants