Power operator (^) precedence levels and evaluation order

조회 수: 21 (최근 30일)
creepydog
creepydog 2024년 6월 21일
댓글: dpb 2024년 7월 21일
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
dpb
dpb 2024년 6월 24일
It will be most interesting to hear the result...
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