Negative Numbers to the power of 0

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
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.
I think -2^0=-1 seems logical. For example, -2^2 = -4 is expected result, instead of -2^2 = 4.
Bruno Luong
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
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
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.
Interesting. I do not recall those special cases from previous readings of the precedence table.
That level (with .^-, .^+, etc.) was added to the list in release R2016a. Compare the R2016a list and the R2015b list.
"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?
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
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.
right to left when unary is present is what the doc that Bruno linked to says...
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
ans =
1.043715416766934
which turns out to be
(2^(3^(-4)))^5
ans =
1.043715416766934
I don't think you could predict that from the documentation :(
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.
What a mess.

Sign in to comment.

 Accepted Answer

Ameer Hamza
Ameer Hamza on 18 Nov 2020
Edited: Ameer Hamza on 18 Nov 2020
You can do it without for-loop
k = 0:4;
x = [-2.0 3.0 9.0 2.0 25.0];
A = x.^(k.')
Also, x(col)^k(row) is equivalent to (-2)^0, not -2^0.
For example, what you you expect the output of following code to be
x = -2;
y = x^2
should y be 4 or -4?

More Answers (1)

TADA
TADA on 18 Nov 2020
Edited: TADA on 18 Nov 2020
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

Thank you for this - learnt something new again
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.
Good point

Sign in to comment.

Asked:

on 18 Nov 2020

Commented:

on 19 Nov 2020

Community Treasure Hunt

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

Start Hunting!