Power function not working as expected
I tried to define random values with arbitrary sign and have come to the conclusion that the power function seems to be implemented in a non-standard fashion. Twig version is 3.4.6 and it is used within the Coderunner extension of Moodle. For testing purposes, I define Twig powers which should be positive or negative, respectively, if the exponent is even or odd.
(-1)^0 = 1: {{ (-1)**0 }}, (-1)^1 = -1: {{(-1)**1}}, (-1)^2 = 1: {{(-1)**2}}
(-2)^0 = 1: {{(-2)**0}} , (-2)^1 = -2: {{(-2)**1}} , (-2)^2 = 4: {{(-2)**2}}
(-1.5)^0 = 1: {{ (-1.5)**0 }} , (-1.5)^1 = -1.5: {{ (-1.5)**1 }} , (-1.5)^2 = 2.25: {{ (-1.5)**2 }}
This does not yield the expected result when interpreting powers with natural exponent as successive multiplication with the zeroth power being the "empty" multiplication which yields the neutral element 1.
(-1)^0 = 1: -1, (-1)^1 = -1: -1, (-1)^2 = 1: -1
(-2)^0 = 1: -1 , (-2)^1 = -2: -2 , (-2)^2 = 4: -4
(-1.5)^0 = 1: -1 , (-1.5)^1 = -1.5: -1.5 , (-1.5)^2 = 2.25: -2.25
The power function seems to set aside any negative sign and put it to the respective power of the absolute value of the base. In a way, this is fine because powers with non-integer exponent are in principle not defined for negative bases because of the definition of general powers as b**c := exp(c*ln(b)) via the exponential function and the natural logarithm where the latter is only defined for positive values. Twig seems to use the following definition instead which yields a value for any power of any base. It has the advantage that any power is defined.
b**c := sign(b)*abs(b)**c = sign(b)*exp(c*ln(abs(b)))
This leads, however, to contradictory results when applying it to base zero.
0^0 = ?: {{ 0**0 }}, 0^1 = 0: {{ 0**0 }}, 0^2 = 0: {{ 0**0 }}
(-0)^0 = ?: {{ (-0)**0 }}, 0^1 = 0: {{ (-0)**0 }}, 0^2 = 0: {{ (-0)**0 }}
Setting aside the fact that 0^0 is mathematically undefined, the results are all wrong and -0 even behaves differently from 0.
0^0 = ?: 1, 0^1 = 0: 1, 0^2 = 0: 1
(-0)^0 = ?: -1, (-0)^1 = 0: -1, (-0)^2 = 0: -1
So on top of the above, Twig seems to define ln(0) := 0 which is simply false. This all is quite unexpected and even confusing. I do see good reasons for having a universally defined function even if non-standard. However, it should be clearly pointed out in the documentation. This may sound pedantic but I had to spend quite some time analysing the problem in depth before discovering the source of the error in my application.
Looking at the compiled template in twigfiddle, the parenthesis are missing when the expression is compiled. ** takes precedence over -.
echo "(-1)^0 = 1: ";
echo twig_escape_filter($this->env, ( -1 ** 0), "html", null, true);