REPL domain error for exponentiation


julia> 2^-10

julia> t = -10

julia> 2^t
ERROR: DomainError with -10:
Cannot raise an integer x to a negative power -10.
Make x or -10 a float by adding a zero decimal (e.g., 2.0^-10 or 2^-10.0 instead of 2^-10), or write 1/x^10, float(x)^-10, x^float(-10) or (x//1)^-10
 [1] throw_domerr_powbysq(::Int64, ::Int64) at ./intfuncs.jl:176
 [2] power_by_squaring(::Int64, ::Int64) at ./intfuncs.jl:197
 [3] ^(::Int64, ::Int64) at ./intfuncs.jl:221
 [4] top-level scope at REPL[40]:1

julia> 2.0^t

Happens in windows, julia 1.3 rc5.1

I think the literal expression takes a different path, possibly going thru this line

        :(literal_pow(^, inv(x), $(Val{-p}())))

at line 255 of intfuncs.jl. There are comments at line 224:

# x^p for any literal integer p is lowered to Base.literal_pow(^, x, Val(p))
# to enable compile-time optimizations specialized to p.

but I don’t understand how code gets dispatched on literals as opposed to Ints. Note that 2^-1 succeeds but 2^Int(-1) does not.


And this

Experimental feature: x^n for integer literals n (e.g. x^3 or x^-3 ) is now lowered to Base.literal_pow(^, x, Val{n}) , to enable compile-time specialization for literal integer exponents (#20530, #20889).

from the Julia v0.6.0 release notes.

Sorry for the multiple posts, you’re seeing me work this out in my slow fashion.

The answer is type safety.

In order for the power function to be type safe with integers, the exponent must be limited to non-negative values. On the other hand, literal expressions, being fixed in value, don’t threaten type safety. As a matter of convenience a literal with a negative exponent is allowed (because it is always a float).