Power operator (^) precedence levels and evaluation order

24 次查看(过去 30 天)
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 个评论
creepydog
creepydog 2024-6-28
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>

请先登录,再进行评论。

采纳的回答

Oliver Jaehrig
Oliver Jaehrig 2024-6-28
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 个评论
Julian Hapke
Julian Hapke 2024-7-21
编辑:dpb 2024-7-21
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 2024-7-21
Interesting, thanks! I was not aware of mtree after 30 years...

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Fortran with MATLAB 的更多信息

产品


版本

R2023b

Community Treasure Hunt

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

Start Hunting!

Translated by