Power operator (^) precedence levels and evaluation order
Show older comments
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 Comments
The linked doc page states: "the operators (^-), (.^-), (^+), (.^+), (^~), and (.^~) work from second from the right to left"
Though unstated (it shouldn't be), presumably the rightmost of those operators is applied last.
In the first example, the "second from the right" is the leftmost operator which is applied first, and then the evaluation finishes with the rightmost operator. So it does go from left to right in that example because there are only two operators.
In the second example, the "second from the right" is the middle operator, then the evaluation works to the left to pick up the leftmost operator, and then the evaluation finishes with the rightmost operator.
So it does look like both examples adhere to the documentation.
Here's another example.
2^-1^-2^3^-4
(2^-(1^-(2^3)))^-4
I vaguely recall another thread on this forum that was a rather long discussion about a similar, if not the exact same, question.
creepydog
on 21 Jun 2024
When using such complicated expressions, I'd make my life easy and safe and place brackets where they need to be placed in order to reflect the expression I want to set. Why spending hours studying MATLAB documentation if a solution with brackets is so simple ?
And I always put negative expressions in brackets although this might not be necessary. Thus 2^(-1) instead of 2^-1.
I too now disagree with my conclusion. I didn't catch that ^ is not the same as ^+ and ^-. Thanks for pointing that out.
creepydog
on 21 Jun 2024
creepydog
on 21 Jun 2024
dpb
on 21 Jun 2024
This (and the other thread) poiint out a problem with proprietary languages such as MATLAB -- it is not required there be a published language specification that unambiguously defines all corners of the language and has an accessible standards group to which one can submit such arcane cases to for resolution -- either explain the rule or cause a correction to be generated in the rare case that an actual problem is uncovered.
MATLAB, otoh, while there undoubtedly is somewhere within TMW (The Mathworks) something that purports to be/serves as such a standard, it is not available outside Natick and all the language definition provided is in the documentation which is, for the most part, example-based rather than be definitive rules.
Hence, there is no way to answer the question raised here with what is publicly available, TMW simply doesn't publish those considered proprietary details for competitive reasons.
One could submit a bug report and see what the response is, but "WAD" (Working as Designed) is probably about all that will be allowed to. Although it could be interesting to see how they might explain the way in which the calculation and the apparent application of the precedence rules differ -- or how the interpretation of the documentation on the rules can be interpreted to come up with the result.
But I don't want to spam unnecessary parentheses everywhere (and waste hours typing and reading them until my retirement).
I also don't like parentheses if they prevent readability of the code. But they are not unnecessary in case of complicated arithmetic structures because they immediately show how they are to be interpreted. You will waste time if you don't structure ambiguous expressions using parentheses because if you open your code after some time, you will have forgotten the software-specific precedence rules and have to consult the MATLAB documentation again (or make test runs as you did if the documentation does not answer what you are looking for).
Paul
on 21 Jun 2024
Surely operator precedence wouldn't be considered a corner of the language. If anything, it's one of the cornerstones of the language.
Even if MathWorks has an an internal, unpublished standards document, the fact is that the operator precedence rules are published and certainly seem to be written with the intent of being definitive (as they should be). Given that's the case, I think it reasonable to expect the documentation be consistent with actual operation (always).
@Paul -- the cases of mixing the two different precedence levels(*) I would submit is a corner -- how sharp of an angle is indeterminate as is the interpretation of the rules as written.
My conjecture is that the internal design document more than likely is definitive but the published description is not an exact translation but an attempt to narratize it into something less complicated. These thoughts are, of course, simply conjecture although the fact that there is no published standard as say, Fortran, C, ..., is fact; all we have is the documentation, not a definition of the language itself.
But, agreed, it would be desireable that the doc were accurate and complete, but the help-writing staff are always bound to leave stuff out and occasionally that may be critical when get to complex issues such as these "made-for-breaking" expressions.
(*) Is there another common language that has such a concept?
Paul
on 22 Jun 2024
Is there another common language that has such a concept as having expressions with operators of two (or more) different precedence levels? I know that you know that is the case in common languages, such as FORTRAN, so I'm sure I'm not understanding the concept to which you are refering.
For Matlab, I don't think there is any reason to distinguish between a standard and the documentation. MathWorks is a closed shop wrt to Matlab, so there shouldn't be any reason to be concerned about whether or not Matlab is compliant with some WG5-like standard, or implements extensions to the standard, etc. like one might be concerned with, say, Digital Visual Fortran. Because MathWorks controls it all, as a user I'm willing to accept that the doc is the de facto standard, even if, as you rightly pointed out, it's not really written like a standard.
Stephen23
on 22 Jun 2024
"Is there another common language that has such a concept?"
All languages must define this (even if their definition is simply "in the order that they occur"):
The ambiguity of human mathematical operators is the reason why improved notations, e.g. reverse polish, have been invented:
dpb
on 22 Jun 2024
@Paul said "For Matlab, I don't think there is any reason to distinguish between a standard and the documentation."
I think this thread disproves that -- and there are many places where the documentation is not complete in its descriptions of what happens although those typically are in higher-level functions rather than the base language.
But, agreed, there is nothing else for the user to go by so when it is either incomplete or wrong (or there is actually a bug in the language), the user has no recourse but to file a bug/support request; there is no reverting back to the Standard to try to make an interpretation oneself as one can at least attempt to do with standardized languages.
And, my bad on the other question raised; I should have reviewed the Fortran standard before writing that, sorry...
Paul
on 22 Jun 2024
If the documentation is not complete or is an error, then, ideally, the documentation needs to be fixed. If there is a bug in the Matlab implementation, then, ideally, that bug should be fixed. I think we agree on this.
For me, all this thread proves is that we have one of those two situations. FWIW, which is probably not much, when I need to deal with other programing languages (e.g., FORTRAN, C++) and need to understand how some code works, I just go to the vendor-provided user's guide, manual, or whatever they call it. I don't think I've ever gone to look up anything in a formal standard. Of course, YMMV.
Based on the historical discussion of this issue, I too have a conjecture as to why Matlab does this (peculiar?) start-from-second-from-the-right thing for bunch of operators, but it's just conjecture.
What I am mildly curious about is whether any other language defines operators analogous to Matlab's ^+ and ^- (and the others at the same precedence as those). I've never seen such, but I'm not knowledgeable about many languages. For example, in FORTRAN
3**-2
is an expression with two operators: exponentiation(**) and unary minus (-), whereas in Matab that expression would use a single operator (^-) .
If you are going to (or already have) opened a support request on this issue, if you don't mind please comment back on this thread with a summary MathWorks's adjudication.
If the documentation is not complete or is an error, then, ideally, the documentation needs to be fixed. If there is a bug in the Matlab implementation, then, ideally, that bug should be fixed. I think we agree on this."
If it is the former, I agree; I have submitted bug/enhancement reports for several corrections/additions to the documentation over the years; most if not all of those have been incorporated.
In this case, if there is actually a discrepancy between what the formal language specification requires(*) and the implementation (and not, as I suspect, simply that the user documentation is not complete in covering all possible combinations of operators and order of each), I would expect it will be the implementation that wins and the specification modified to match--there's simply too much precedence and historical code (including MATLAB/Mathworks code itself) to go munging on this.
(*) I continue in my belief there simply has to be such internally
"If you are going to (or already have) opened a support request on this issue, ..."
I think it is a case where a support request should indeed be submitted asking for clarification of the rules and that the documentation be amplified to be complete and unambiguous. I do not disagree with the general precept that lacking the formal design document to refer to, the user documentation should serve in its stead. The problem TMW has is that they chose to make the documentation example and narrative based(+) in order to try to be "user friendly" and consequently normative text gets the short end of the stick when things get sticky as here.
(+) It's annoying the Examples section comes before the normative definition of arguments although sometimes it's only by a combination of studying both one can finally understand some of the more complex syntax.
creepydog
on 24 Jun 2024
dpb
on 24 Jun 2024
It will be most interesting to hear the result...
creepydog
on 28 Jun 2024
Accepted Answer
More Answers (0)
Categories
Find more on Software Development in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!