From fdbae11e31bbe8edb9620ddba82c6747b9ddc9f3 Mon Sep 17 00:00:00 2001 From: oscarddssmith <oscar.smith@juliacomputing.com> Date: Thu, 21 Oct 2021 13:56:38 -0400 Subject: [PATCH 1/3] fix overflow and undeflow for @fastmath exp --- base/special/exp.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/base/special/exp.jl b/base/special/exp.jl index 7e7f9b100b439..83b8e1b15e480 100644 --- a/base/special/exp.jl +++ b/base/special/exp.jl @@ -253,6 +253,8 @@ end return reinterpret(T, twopk + reinterpret(Int64, small_part)) end @inline function exp_impl_fast(x::Float64, base) + x >= MAX_EXP(base, T) && return Inf + x <= -SUBNORM_EXP(base, T) && return 0.0 T = Float64 N_float = muladd(x, LogBo256INV(base, T), MAGIC_ROUND_CONST(T)) N = reinterpret(UInt64, N_float) % Int32 @@ -287,6 +289,8 @@ end end @inline function exp_impl_fast(x::Float32, base) + x >= MAX_EXP(base, T) && return Inf32 + x <= -SUBNORM_EXP(base, T) && return 0f0 T = Float32 N_float = round(x*LogBINV(base, T)) N = unsafe_trunc(Int32, N_float) From 6c9e2b98a774f5dbd0cf86815e798d26b077551c Mon Sep 17 00:00:00 2001 From: oscarddssmith <oscar.smith@juliacomputing.com> Date: Thu, 21 Oct 2021 14:09:51 -0400 Subject: [PATCH 2/3] fixed --- base/special/exp.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/special/exp.jl b/base/special/exp.jl index 83b8e1b15e480..d9afd4c7134c9 100644 --- a/base/special/exp.jl +++ b/base/special/exp.jl @@ -253,9 +253,9 @@ end return reinterpret(T, twopk + reinterpret(Int64, small_part)) end @inline function exp_impl_fast(x::Float64, base) + T = Float64 x >= MAX_EXP(base, T) && return Inf x <= -SUBNORM_EXP(base, T) && return 0.0 - T = Float64 N_float = muladd(x, LogBo256INV(base, T), MAGIC_ROUND_CONST(T)) N = reinterpret(UInt64, N_float) % Int32 N_float -= MAGIC_ROUND_CONST(T) #N_float now equals round(x*LogBo256INV(base, T)) @@ -289,9 +289,9 @@ end end @inline function exp_impl_fast(x::Float32, base) + T = Float32 x >= MAX_EXP(base, T) && return Inf32 x <= -SUBNORM_EXP(base, T) && return 0f0 - T = Float32 N_float = round(x*LogBINV(base, T)) N = unsafe_trunc(Int32, N_float) r = muladd(N_float, LogBU(base, T), x) From e8d5678be18370503a58d8a76917e942760210e5 Mon Sep 17 00:00:00 2001 From: Oscar Smith <oscardssmith@gmail.com> Date: Thu, 21 Oct 2021 22:44:55 -0400 Subject: [PATCH 3/3] add tests --- test/fastmath.jl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/fastmath.jl b/test/fastmath.jl index edaab1c6eb0cf..e93fb93330b4f 100644 --- a/test/fastmath.jl +++ b/test/fastmath.jl @@ -249,3 +249,13 @@ end @test (@fastmath "a" * "b") == "ab" @test (@fastmath "a" ^ 2) == "aa" end + + +@testset "exp overflow and underflow" begin + for T in (Float32,Float64) + for func in (@fastmath exp2,exp,exp10) + @test func(T(2000)) == T(Inf) + @test func(T(-2000)) == T(0) + end + end +end