Skip to content

Commit 03433a2

Browse files
authored
fix negative numbers to powers >2^64 (#44456)
*fix negative numbers to powers >2^64
1 parent dc45d77 commit 03433a2

File tree

2 files changed

+8
-0
lines changed

2 files changed

+8
-0
lines changed

base/math.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,8 @@ end
999999
@constprop :aggressive function ^(x::Float64, y::Float64)
10001000
yint = unsafe_trunc(Int, y) # Note, this is actually safe since julia freezes the result
10011001
y == yint && return x^yint
1002+
#numbers greater than 2*inv(eps(T)) must be even, and the pow will overflow
1003+
y >= 2*inv(eps()) && return x^(typemax(Int64)-1)
10021004
x<0 && y > -4e18 && throw_exp_domainerror(x) # |y| is small enough that y isn't an integer
10031005
x == 1 && return 1.0
10041006
return pow_body(x, y)
@@ -1017,6 +1019,8 @@ end
10171019
@constprop :aggressive function ^(x::T, y::T) where T <: Union{Float16, Float32}
10181020
yint = unsafe_trunc(Int64, y) # Note, this is actually safe since julia freezes the result
10191021
y == yint && return x^yint
1022+
#numbers greater than 2*inv(eps(T)) must be even, and the pow will overflow
1023+
y >= 2*inv(eps(T)) && return x^(typemax(Int64)-1)
10201024
x < 0 && y > -4e18 && throw_exp_domainerror(x) # |y| is small enough that y isn't an integer
10211025
return pow_body(x, y)
10221026
end

test/math.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@ end
155155
@test x^y === T(big(x)^big(y))
156156
@test x^1 === x
157157
@test x^yi === T(big(x)^yi)
158+
# test (-x)^y for y larger than typemax(Int)
159+
@test T(-1)^floatmax(T) === T(1)
160+
@test prevfloat(T(-1))^floatmax(T) === T(Inf)
161+
@test nextfloat(T(-1))^floatmax(T) === T(0.0)
158162
# test for large negative exponent where error compensation matters
159163
@test 0.9999999955206014^-1.0e8 == 1.565084574870928
160164
@test (-x)^yi == x^yi

0 commit comments

Comments
 (0)