JuliaLang / julia

The Julia Programming Language
https://julialang.org/
MIT License
45.04k stars 5.43k forks source link

`Base.literal_pow` undesired floating-point conversion for base of `±1`? #53735

Open oscardssmith opened 4 months ago

oscardssmith commented 4 months ago
julia> Base.literal_pow(^, -1, Val(-1))
-1.0

julia> y = -1
-1

julia> (-1)^y
-1

This has been broken since at least 1.6

nhz2 commented 4 months ago

I don't think this is a bug because the docs for ^ says.

If y is a negative integer literal, then Base.literal_pow transforms the operation to inv(x)^-y by default, where -y is positive.

and inv(-1) is -1.0

I think the reason for this is so that functions like foo(x::Int) = x^-1 are type stable.

oscardssmith commented 4 months ago

the problem here is that one of the fundamental properties of literal pow is that it doesn't change the results for inputs where x^y returns an answer.

KlausC commented 4 months ago

IMO the problem is, that literal_pow(x, Val{-1}) cannot be type stable and at the same time behave like x^Int(-1), because the latter throws DomainError for x = 2 while the first is supposed to return 0.5. In order to be type stable, it has to return 1.0 for x = 1 then.

stevengj commented 3 months ago

I'm removing the "bug" label since this is the intended behavior for negative literal powers, regardless of the base, and it's not clear whether anything can or should be changed here in a type-stable way.