Power operator (^) precedence levels and evaluation order

20 visualizaciones (últimos 30 días)
creepydog
creepydog el 21 de Jun. de 2024
Comentada: dpb el 21 de Jul. de 2024
While
2^-1^-2
returns 4, which indicates a "left to right" evaluation order (as it is common in many programming languages),
2^-1^-2^3
returns 0.125, which I find surprising – I would have expected a value of 4^3 = 64.
To examine the order applied by Matlab, I tried all possible combinations:
((2^-1)^-2)^3 % returns 64 (1st, then 2nd operator)
(2^-1)^-(2^3) % returns 256 (1st and 3rd)
(2^-(1^-2))^3 % returns 0.125 (2nd, then 1st)
2^-((1^-2)^3) % returns 0.5 (2nd, then 3rd)
2^-(1^-(2^3)) % returns 0.5 (3rd, then 2nd)
So it seems that Matlab first evaluates the 2nd operator, then the 1st (=left), then the 3rd (=rightmost). That seems very odd. Can anybody explain why Matlab chooses this evaluation order?
I'm aware of https://de.mathworks.com/help/matlab/matlab_prog/operator-precedence.html, but it just doesn't make sense to me. According to the rules given there, the 3rd operator (^) in my example should even come first, as it has a higher precedence than the other two (^-) operators. So doesn't Matlab adhere to its own rules?
  18 comentarios
dpb
dpb el 24 de Jun. de 2024
It will be most interesting to hear the result...
creepydog
creepydog el 28 de Jun. de 2024
TMW has answered my support request (see accepted answer), which referred to this thread but contained its own example and focus. The answer isn't 42, but the corresponding question shouldn't be unknown anyway. So, for completeness and transparency, I'd like to post the full text of my support request here:
<quote>
If you run this expression in the Command Window:
>> 2^+3^2
Matlab returns ans = 64, which shows that it was evaluated from left to right, i.e. as (2^+3)^2. Otherwise the result would be 512.
The operator precedence documentation [1] says that there are two different precedence levels for power operators (levels 2 and 3). The normal matrix power operator ^ has precedence level 2, while the "matrix power with unary plus" operator ^+ has level 3, which is inferior to level 2. So, according to the documentation, 2^+3^2 should be evaluated as 2^+(3^2), because the ^ operator has higher precedence than ^+ (like 2+3*4 is 14, not 20).
There's a note in the documentation [1] saying that level 3 operators deviate from the normal left-to-right rule [2], but that only matters within (!) this precedence level 3. Operators of precedence level <= 2 still have priority over operators of level 3, so ^ must precede ^+ according to the documentation, regardless of left/right aspects.
Please also see my question and the discussion with/of several MVPs in Matlab Central [3] for more examples and thoughts about this problem.
[2] They "work from second from the right to left", I'm not sure what that means, linguistically.
</quote>

Iniciar sesión para comentar.

Respuesta aceptada

Oliver Jaehrig
Oliver Jaehrig el 28 de Jun. de 2024
The statement below is coming from our development team and they reviewed the discussion on MATLAB Answers and the incoming support request regarding it:
We agree that the current behavior is unusual. Unfortunately, it's decades-old MATLAB behavior. We may choose to change it, but it cannot change suddenly without adequate notice.
We strongly recommend using parentheses to clarify the intended order of operations. The Code Analyzer suggests this, and early versions of MATLAB actually required this.
To clarify what is meant by "second from the right to left" in the doc,
a^-b^-c^-d^-e^-f
is parsed as
(a ^ (- (b ^ (- (c ^ (- (d ^ (- e)))))))) ^ (- f)
which is essentially equivalent to
X1 = -(d^-e);
X2 = -(c^X1);
X3 = -(b^X2);
X4 = a^X3;
X5 = X4^-f
Our development team considers to enhance the documentation about this in a future release. If there are any further questions, please let me know, or create a new support request if needed.
  18 comentarios
Julian Hapke
Julian Hapke el 21 de Jul. de 2024
Editada: dpb el 21 de Jul. de 2024
You can see how MATLAB evaluates an expression by using the mtree function. It does indeed not recognize ^+ as it's own operator, but as soon as there is a unary operator inside an exponent, it influences the abstract syntax tree of the whole expression, e.g.:
```
dump(mtree('5 ^ 4 ^ 3 ^ 2'))
1=== * PRINT: 1/11
2=== * EXP: 1/11
3=== * EXP: 1/07
4=== * EXP: 1/03
5=== * INT: 1/01 (5)
6=== * INT: 1/05 (4)
7=== * INT: 1/09 (3)
8=== * INT: 1/13 (2)
dump(mtree('5 ^+ 4 ^ 3 ^ 2'))
1=== * PRINT: 1/12
2=== * EXP: 1/12
3=== * EXP: 1/03
4=== * INT: 1/01 (5)
5=== * UPLUS: 1/04
6=== * EXP: 1/08
7=== * INT: 1/06 (4)
8=== * INT: 1/10 (3)
9=== * INT: 1/14 (2)
```
5 ^ 4 ^ 3 ^ 2 == (((5 ^ 4) ^ 3) ^ 2)
and
5 ^+ 4 ^ 3 ^ 2 == (5 ^+ (4 ^ 3)) ^ 2
dpb
dpb el 21 de Jul. de 2024
Interesting, thanks! I was not aware of mtree after 30 years...

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Fortran with MATLAB en Help Center y File Exchange.

Productos


Versión

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by