Negative Numbers to the power of 0
Show older comments
Hi All,
New-again matlab user after a decade away; having trouble with raising a negative number to the power 0.
I recognise that:
- (-2)^0 = 1 and
- -2^0 = -1.
In my code, I am trying to populate a 5x5, row by row filling the columns with elements of one 1x5 row vector to the power of another 1x5 vector.
I have written a very basic, and probably inefficient way of doing this with two for loops, but when it comes to raising a negative number to the power 0 and storing it, I get 1 as opposed to what I think is correct; -1.
I presume Im missing something very basic but would really appreciate any help; Thank you!
k = [0:4]
x = [-2.0 3.0 9.0 2.0 25.0]
A = ones(5,5);
for row = 1:length(k)
for col = 1:length(k)
A(row,col) = x(col)^k(row);
end
end
This is what I get: But I think the top left should be -1 since -2^0 = -1
1 1 1 1 1
-2 3 9 2 25
4 9 81 4 625
-8 27 729 8 15625
16 81 6561 16 390625
15 Comments
Bruno Luong
on 18 Nov 2020
Edited: Bruno Luong
on 18 Nov 2020
Interesting, I didn't know -2^0 returns -1.
I though it should be interpreted by the parser as (-2)^0 (which is 1) and not -(2^0) (which is -1)
Anyway the matrix elementwise power result matches the scalar power. I don't see the reason you expect to be -1.
Ameer Hamza
on 18 Nov 2020
I think -2^0=-1 seems logical. For example, -2^2 = -4 is expected result, instead of -2^2 = 4.
Bruno Luong
on 18 Nov 2020
Edited: Bruno Luong
on 18 Nov 2020
(-2)^2 is (-2)*(-2) = 4.
I though the parser of expression "-2^2" attaches the "-" to the number (return a negative number) THEN takes this (negative) number a square it. Obviously it considers "-" as unitary minus operator uminus applied on 2^2.
Walter Roberson
on 18 Nov 2020
Edited: Bruno Luong
on 18 Nov 2020
Most languages treat unary minus as binding more tightly than ^ but not all of them.
MATLAB is inconsistent in how it prioritizes - so for example 3^-5 is valid for raising a number to a negative power, which should mean that - has higher priority than ^ but it does not in the expression -3^5 .
Maple is at least consistent and so considers 3^-5 a parsing error for having two operators in a row.
Bruno Luong
on 18 Nov 2020
Edited: Bruno Luong
on 18 Nov 2020
" which should mean that - has higher priority than ^ "
Actually officially no according to the doc file
But I agree that in 3^-5 there is NO other choice than of applying "-" to 5 first. But this is NOT the right interpretation. MATLAB actually considers "^-" as SINGLE operator (see item 3 of the above doc). There is no cascading for us to understand or consistency failure.
Walter Roberson
on 18 Nov 2020
Interesting. I do not recall those special cases from previous readings of the precedence table.
Steven Lord
on 18 Nov 2020
That level (with .^-, .^+, etc.) was added to the list in release R2016a. Compare the R2016a list and the R2015b list.
James Tursa
on 18 Nov 2020
"Most languages treat unary minus as binding more tightly than ^ but not all of them"
I would have said exactly the opposite. Fortran and Basic treat ^ (which is ** in Fortran) higher than unary minus, and so does MATLAB. This is exactly what I would expect. What language that has an exponentiation operator does this differently?
Bruno Luong
on 18 Nov 2020
Edited: Bruno Luong
on 18 Nov 2020
The way it works is just weird, wonder what is the thing behind the decision of different precedence with ^+
>> 2^3^4^5
ans =
1.1529e+18
>> ((2^3)^4)^5 % this is the order of "^", left to right
ans =
1.1529e+18
>> +2^+3^+4^+5
ans =
8.2632e+121
>> (2 ^ (3 ^ 4)) ^ 5 % this must be the order with "^+", right to left fron second !!!
ans =
8.2632e+121
However if we remove ^+5
>> 2^+3^+4
ans =
4096
>> (2^3)^4 % suddendly this is the order
ans =
4096
>> 2^(3^4) % and NOT this
ans =
2.4179e+24
James Tursa
on 18 Nov 2020
Edited: James Tursa
on 18 Nov 2020
The left-to-right order of ^ in MATLAB is something that does differ from Fortran. Fortran does exponentiation ** operator right-to-left. I have no idea why MATLAB chose to implement it different from Fortran ... only TMW could speak to that.
The +2^+3^+4^+5 example looks like a parsing error in MATLAB quite frankly.
Walter Roberson
on 18 Nov 2020
right to left when unary is present is what the doc that Bruno linked to says...
James Tursa
on 18 Nov 2020
Edited: James Tursa
on 18 Nov 2020
But if it really was right-to-left when unary is present I would expect these two to be the same:
>> 2^+3^+4^+5
ans =
8.2632e+121
>> 2^+(3^+(4^+5))
ans =
Inf
But they aren't. So I can't treat the ^+ combination as a single operator and do it right-to-left. I guess that is what the doc means by "second from right to left". So maybe not a parsing error according to the doc ... it just looks like one to the uninitiated.
And I agree with Bruno that it is just weird that ^ is left-to-right but ^+ and ^- are "second from right to left". Exponentiation with unary + and - get their own goofy ordering rules for some reason ...
It is almost as if TMW simply tried to document how the parser behaves in certain situations instead of coding the parser to do something consistent in these cases.
Bottom Line: Use parentheses!
Try to predict what +2^+3^-4^5 evaluates to:
format long
+2^+3^-4^+5
which turns out to be
(2^(3^(-4)))^5
I don't think you could predict that from the documentation :(
James Tursa
on 18 Nov 2020
This is essentially the same example that Bruno gave. So the doc phrase "second from the right to left" means that you recursively do the operator that is second from the right as you process the operations. The rightmost operator is done last. E.g.,
>> 1.2^+1.3^+1.4^+1.5^+1.6^+1.7
ans =
1.6665
>> (1.2^+(1.3^+(1.4^+(1.5^+1.6))))^+1.7
ans =
1.6665
Good luck trying to remember that ... and better luck trying to get things straight if you mix in the regular ^ operator anywhere.
Bruno Luong
on 18 Nov 2020
What a mess.
Accepted Answer
More Answers (1)
Any arithmetic operation performed on variables will treat the variables as if it was wrapped with parentheses.
Try this simple example:
x = -2;
y = x^0
y = 1
In my opinion, this is the correct result, which takes into account the proper order of operations, but if you really want that to keep the original sign, you can multiply your result by the sign of the original number:
y = sign(x) * x^0
y = -1
3 Comments
Simon Hunter
on 18 Nov 2020
Les Beckham
on 19 Nov 2020
One caveat:
If x = 0, then the sign(x) * x^0 trick won't work to 'keep the original sign' while also returning the correct result.
Note that 0^1 = 1 but sign(0)*0^0 = 0, since sign(0) = 0 in Matlab.
TADA
on 19 Nov 2020
Good point
Categories
Find more on Matrix Indexing 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!