diff --git a/src/NaNMath.jl b/src/NaNMath.jl index d7877bf..7fdb4bc 100644 --- a/src/NaNMath.jl +++ b/src/NaNMath.jl @@ -68,6 +68,12 @@ Base.@assume_effects :total pow(x::Float32, y::Float32) = ccall((:powf,libm), Fl # e.g. `pow(::Float32, ::Int)` ends up calling `pow(::Float32, ::Float32)` pow(x::Real, y::Real) = pow(promote(x, y)...) pow(x::T, y::T) where {T<:Real} = pow(float(x), float(y)) +function pow(x::T, y::T) where {T<:AbstractFloat} + if x < 0 && !isinteger(y) + return T(NaN) + end + return x ^ y +end pow(x, y) = ^(x, y) # The following combinations are safe, so we can fall back to ^ diff --git a/test/runtests.jl b/test/runtests.jl index 1528507..3f173f2 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3,8 +3,10 @@ using Test @test isnan(NaNMath.log(-10)) @test isnan(NaNMath.log1p(-100)) -@test isnan(NaNMath.pow(-1.5,2.3)) -@test isnan(NaNMath.pow(-1.5f0,2.3f0)) +for T in (Float16, Float32, Float64, BigFloat) + @test isnan(NaNMath.pow(T(-1.5),T(2.3))) + @test NaNMath.pow(T(-1.5),T(5)) ≈ T(-1.5) ^ T(5) +end @test isnan(NaNMath.pow(-1.5,2.3f0)) @test isnan(NaNMath.pow(-1.5f0,2.3)) @test NaNMath.pow(-1.5f0,2) isa Float32