There is something strange that I do not understand:

```
julia> 2^-3
0.125
```

works ok. But the following minor generalization does not.

```
julia> g() = -3; 2^g()
ERROR: DomainError with -3:
Cannot raise an integer x to a negative power -3.
Make x or -3 a float by adding a zero decimal (e.g., 2.0^-3 or 2^-3.0 instead of 2^-3)or write 1/x^3, float(x)^-3, x^float(-3) or (x//1)^-3.
Stacktrace:
[1] throw_domerr_powbysq(::Int64, p::Int64)
@ Base ./intfuncs.jl:265
[2] power_by_squaring(x_::Int64, p::Int64)
@ Base ./intfuncs.jl:286
[3] ^(x::Int64, p::Int64)
@ Base ./intfuncs.jl:310
[4] top-level scope
@ REPL[2]:1
```

of course

```
julia> 2.0^g()
0.125
```

works. I tried to `descend`

into the call but did not find where `2^g()`

misses the promotion to `2.0^g()`

. I do not think it is a bug, but I do not see the rationale behind this behavior.

Thanks

From documentation on `^`

:

If y is an Int literal (e.g. 2 in x^2 or -3 in x^-3), the Julia code x^y is transformed by the compiler to Base.literal_pow(^, x, Val(y)), to enable compile-time specialization on the value of the exponent. (As a default fallback we have Base.literal_pow(^, x, Val(y)) = ^(x,y), where usually ^ == Base.^ unless ^ has been defined in the calling namespace.) If y is a negative integer literal, then Base.literal_pow transforms the operation to inv(x)^-y by default, where -y

is positive.

```
julia> Base.literal_pow(^, 3, Val(-3))
0.037037037037037035
```

`g()`

in `2^g()`

is not a literal, so this transformation does not happen.

1 Like

Thanks @barucden … I overlooked the docs. Marking your reply as a solution.

Yet, it is not completely clear why `2^g()`

where g() is inferred to be an `Int`

should behave differently. g() is not a literal true, but there should be a code path where literal_pow and pow should behave the same for provably integer exponents.

This is not just about the exponent being an integer, but being a *specific* integer. Cf. Confusing difference: ^literal vs ^variable - #6 by StefanKarpinski for some rationale.