diff --git a/src/dual.jl b/src/dual.jl index 7552dd5f..0c5d5ebc 100644 --- a/src/dual.jl +++ b/src/dual.jl @@ -576,7 +576,7 @@ for (f, log) in ((:(Base.:^), :(Base.log)), (:(NaNMath.pow), :(NaNMath.log))) begin v = value(y) expv = ($f)(x, v) - deriv = (iszero(x) && v > 0) ? zero(expv) : expv*($log)(x) + deriv = (iszero(x) && v > 0) ? zero(expv) : expv*($log)(oftype(expv, x)) return Dual{Ty}(expv, deriv * partials(y)) end ) diff --git a/test/DualTest.jl b/test/DualTest.jl index df9f9dcb..03021b9d 100644 --- a/test/DualTest.jl +++ b/test/DualTest.jl @@ -499,6 +499,14 @@ ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false @test partials(NaNMath.pow(Dual{TestTag}(-2.0, 1.0), Dual{TestTag}(2.0, 0.0)), 1) == -4.0 + # differentiating must not widen the primal: `2^x` is Float32 for a Float32 `x` + @testset "$f: real base keeps $W exponent" for f in (^, NaNMath.pow), + W in (Float16, Float32, Float64) + w = W(4)/W(3) + @test typeof(value(f(2, Dual{TestTag}(w, one(W))))) === typeof(f(2, w)) + @test typeof(value(f(2.0f0, Dual{TestTag}(w, one(W))))) === typeof(f(2.0f0, w)) + end + ################################### # General Mathematical Operations # ###################################