Discussion:
[Tutor] a puzzle about -3**2 vs (-3)**2
D Wyatt
2015-07-31 00:58:27 UTC
Permalink
I just read in a book a little while ago that ** trumps a negative
sign? I am struggling with the audacity of that as -1 is negative 1,
NOT minus 1. How can an arithmetic operation trump an attribute of a
negative integer? It truly makes no sense to me. Thank you for any
enlightenment you can provide.

Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:43:06) [MSC v.1600 32 bit (In
tel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
3**2
9
(-3)**2
9
-3**2
-9
--
Deb Wyatt in WA
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Alan Gauld
2015-07-31 09:18:14 UTC
Permalink
Post by D Wyatt
I just read in a book a little while ago that ** trumps a negative
sign? I am struggling with the audacity of that as -1 is negative 1,
NOT minus 1. How can an arithmetic operation trump an attribute of a
negative integer?
Because Python is a programming language with its own rules
created by its designer. It doesn't need to follow the rules
of math as you understand them.

The decision may have been made because it made parsing
constructs like this easier:

5-2

Is that 2 adjacent numbers 5 and -2? or is it an infix subtraction?
Its easy for us to decide but harder for a computer reading the text.
As the expressions get more complex there are more and more potentially
ambiguous combinations so the language designer may decide to make the
language more consistent by defining a set of precedence rules. In
this case that ** is higher than -.

He is quite within his rights to do that. It's his language after all.
Some languages solve these problems by not permitting infix notation,
so in Lisp for example

(3 - 5)

is illegal, you need to do

(- 3 5)

It looks odd to us but that's not the point, its how the language works.
You learn to get used to it. Most languages have some idiosyncrasies
like this.

HTH
--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Alan Gauld
2015-07-31 18:51:37 UTC
Permalink
Post by Alan Gauld
It looks odd to us but that's not the point, its how the language works.
You learn to get used to it. Most languages have some idiosyncrasies like
this.
Yes, I understand that the creator of the language can make it work
however he wants, but I was really hoping for a logical answer. Just
because 'that's the way it is' kind of sucks and will make it more
difficult to remember.
Many languages do their own thing because it makes the compiler go faster,
or makes the code produced more reliable/consistent. That's often more
important to a language designer than making it intuitive to the reader.

In fact, some languages deliberately use a different set of
rules/notation because
the language designer believes that his/her way is superior to the
traditional
notation and uses the language to test those ideas.

Now, as others have pointed out, Python does in fact follow traditional
math
in most things, so is usually intuitively correct, but you should never
assume
that of any programming language. The designers are often reaching for
different
targets than the eventual user. And very often we the users don't know what
the designer's aims or priorities were. (For example Forth was designed
to fit
into the very small amount of memory left over on an astronomical telescope
control system, so is very, very terse, and uses many "illogical" code
layouts.
Everything was sacrificed to save space.)

Of course as users we get to decide whether the designers choices are
acceptable to us or whether we will adopt another language. Many
experimental languages full of good, powerful programming ideas never
made it into common use precisely because they chose some weird syntax
or layout convention that was just too far out for programmers to accept.
--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos

_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Válas Péter
2015-07-31 19:22:33 UTC
Permalink
(For example Forth was designed to fit
into the very small amount of memory left over on an astronomical telescope
control system, so is very, very terse, and uses many "illogical" code
layouts.
Everything was sacrificed to save space.)
Thank you for this interesting story, I never knew this. You mentioned such
interesting languages as Lisp and Forth. While you are right that operator
precedence may vary from language to language (just a few weeks ago PHP
schocked me with the different precedence of and/or and "C-style" &&/|| and
it took me quite a time to find the error), I think we may say that all the
mainstream languages of present times leave the precedence of ARITHMETICAL
operators intact among each other. And this follows the rules of elementary
math.

While thinking that minus is glued to the following number has its own
logic and is not hard to understand this logic, it's not the rule of
mathematics. That's why math has its worldwide accepted rules, and that's
why these are taught in schools whereever we go on the globe. These rules
are also based on logics, of course. And because prorgramming is a branch
of applied mathematics, it is really-really worth to keep the rules of math
-- I think where they are broken, it is an exception and not the normal
workflow.

While all we should read the famous manual concerning the precedence when
we learn a new language, we may trust that * will always preceed +, ** will
preceed any other arithmetical operator, and AND will preceed OR -- unless
we deal with some special/obscure/historical language. Python is not an
exception.
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Todd
2015-07-31 09:07:31 UTC
Permalink
Post by D Wyatt
I just read in a book a little while ago that ** trumps a negative
sign? I am struggling with the audacity of that as -1 is negative 1,
NOT minus 1. How can an arithmetic operation trump an attribute of a
negative integer? It truly makes no sense to me. Thank you for any
enlightenment you can provide.
Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:43:06) [MSC v.1600 32 bit (In
tel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
3**2
9
(-3)**2
9
-3**2
-9
It is a matter of operator precedence. Certain operators are carried out
before others. See here:
https://docs.python.org/3/reference/expressions.html#operator-precedence

Negation has lower precedence than exponentiation. That means that the
exponentiation is carried out first, and negation is carried out second.
So "-3**2" is equivalent to "-(3**2)".

This matches the precedence rules for written mathematics, where negation
has a lower precedence than exponentiation as well. So python is doing the
correct thing here mathematically. See, for example,
http://mathforum.org/library/drmath/view/53194.html
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
D Wyatt
2015-07-31 17:20:50 UTC
Permalink
<snip>
Post by Todd
This matches the precedence rules for written mathematics, where negation
has a lower precedence than exponentiation as well. So python is doing the
correct thing here mathematically. See, for example,
http://mathforum.org/library/drmath/view/53194.html
_______________________________________________
https://mail.python.org/mailman/listinfo/tutor
That is just so counterintuitive, and I've never run into this in any
mathematics I have taken. Now I'm going to have to research this
further, from a mathematics standpoint.
--
Deb Wyatt in WA
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Steven D'Aprano
2015-08-01 16:43:20 UTC
Permalink
Hi Deb,
Post by D Wyatt
<snip>
Post by Todd
This matches the precedence rules for written mathematics, where negation
has a lower precedence than exponentiation as well. So python is doing the
correct thing here mathematically. See, for example,
http://mathforum.org/library/drmath/view/53194.html
[...]
Post by D Wyatt
That is just so counterintuitive, and I've never run into this in any
mathematics I have taken. Now I'm going to have to research this
further, from a mathematics standpoint.
You have inspired me to do a bit more research.

I've found at least three programming languages that behave as you
expect: the programming language "bc", Xion, and Microsoft Excel
formulae. For instance, Xion evaluates -3^2 as 9.

And proving that you're damned if you do and damned if you don't, here
is a bug report filed against Excel, stating that -2^2 returns 4 instead
of the expected result -4:

https://support.microsoft.com/en-gb/kb/kbview/132686

My favourite scientific calculator, the HP 48GX, uses Reverse Polish
Notation by default and so the question of operator precedence doesn't
come up. But it also has an optional algebraic mode, and '-2^2'
evaulates as -4.

Javascript doesn't have a power operator. Neither does C, one of the
most widely-used languages in the world.

Ruby agrees with Python:

irb(main):001:0> -3**2
=> -9

According to Wikipedia:

https://en.wikipedia.org/wiki/Order_of_operations

some scientific journals now treat multiplication as a higher precedence
than division with a / so that 1/2x equals 1/(2x), not (1/2)x.

There's an interesting study done here:

"Developer beliefs about binary operator precedence"

http://www.knosof.co.uk/cbook/accu06.html

which suggests that even professional programmers get operator
precedence wrong at a high rate. (The study found a 33% error rate.)

The bottom line is, there is no universal right or wrong answer for the
precedence rules for operators, although some rules are less right than
others.
--
Steve
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Emile van Sebille
2015-08-01 16:53:37 UTC
Permalink
Post by Steven D'Aprano
The bottom line is, there is no universal right or wrong answer for the
precedence rules for operators, although some rules are less right than
others.
My bottom line is that the liberal use of parens reconciles them all,
particularly for any humans reading the code that need to change it.

Emile





_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
D Wyatt
2015-08-02 00:26:27 UTC
Permalink
<snip>
Post by Steven D'Aprano
https://en.wikipedia.org/wiki/Order_of_operations
some scientific journals now treat multiplication as a higher precedence
than division with a / so that 1/2x equals 1/(2x), not (1/2)x.
"Developer beliefs about binary operator precedence"
http://www.knosof.co.uk/cbook/accu06.html
which suggests that even professional programmers get operator
precedence wrong at a high rate. (The study found a 33% error rate.)
The bottom line is, there is no universal right or wrong answer for the
precedence rules for operators, although some rules are less right than
others.
--
Steve
Interesting info. Thanks for following up on this.
--
Deb Wyatt in WA
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Jose Amoreira
2015-07-31 09:55:19 UTC
Permalink
Hello!
Post by D Wyatt
I just read in a book a little while ago that ** trumps a negative
sign? I am struggling with the audacity of that as -1 is negative 1,
NOT minus 1.
I'm not sure about what you mean by "trumps", but the square of negative
one is positive one (negative times negative gives positive).
Post by D Wyatt
How can an arithmetic operation trump an attribute of a
negative integer? It truly makes no sense to me. Thank you for any
enlightenment you can provide.
Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:43:06) [MSC v.1600 32 bit (In
tel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
3**2
9
(-3)**2
9
-3**2
-9
Given the precedence rules already mentioned by Alan and Todd, the
results of the operations you showed us are exactly as expected. You'll
get the same results if you try with a pocket calculator or using any
other programming language or scientific package. Or MS-excel.

HTH,
Ze
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Alan Gauld
2015-07-31 10:36:22 UTC
Permalink
Post by Jose Amoreira
Given the precedence rules already mentioned by Alan and Todd, the
results of the operations you showed us are exactly as expected. You'll
get the same results if you try with a pocket calculator or using any
other programming language or scientific package.
The point I was making is that you may NOT get the same results in any
other language. Each language designer is free to define his/her own
precedence rules. Most try to follow the rules of math, but some do not
(like Lisp using prefix notation rather than infix). Several languages
evaluate purely left to right, at least 1 goes from right to left.

In programming you have to learn the language and not expect it to
conform to any preconceived ideas of how it *should* work.
--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Jose Amoreira
2015-07-31 10:45:14 UTC
Permalink
Post by Alan Gauld
Post by Jose Amoreira
Given the precedence rules already mentioned by Alan and Todd, the
results of the operations you showed us are exactly as expected. You'll
get the same results if you try with a pocket calculator or using any
other programming language or scientific package.
The point I was making is that you may NOT get the same results in any
other language. Each language designer is free to define his/her own
precedence rules. Most try to follow the rules of math, but some do not
(like Lisp using prefix notation rather than infix). Several languages
evaluate purely left to right, at least 1 goes from right to left.
In programming you have to learn the language and not expect it to
conform to any preconceived ideas of how it *should* work.
Yes, you are right, Alan. That expectation is often the source of much
frustration when learning a new language.
But, for this particular application, this particular language even
conforms to those general preconceived ideas... And I'm glad it does!

:)
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Válas Péter
2015-07-31 10:04:09 UTC
Permalink
3**2
9
(-3)**2
9
-3**2
-9
Try to get any other result for these operations in a primary school paper,
and then have a look at your marks...
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Válas Péter
2015-07-31 18:10:06 UTC
Permalink
Post by Válas Péter
Post by Válas Péter
Try to get any other result for these operations in a primary school
paper,
Post by Válas Péter
and then have a look at your marks...
Condescending and unhelpful response. Why did you bother?
I tell you another way. These ARE the arithmetically correct results. Why
do you expect Python give wrong ones?
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Steven D'Aprano
2015-07-31 12:12:51 UTC
Permalink
Post by D Wyatt
I just read in a book a little while ago that ** trumps a negative
sign?
Correct. Exponentiation has higher priority than subtraction, addition,
multiplication and division:

2+3**2 => 11 not 25

10-3**2 => 1 not 49

2*3**2 => 18 not 36

100/5**2 => 4 not 400

As you have discovered, it also has higher priority than unary minus so
that:

-3**2 => -(3**2) => -9 NOT (-3)**2 => 9

Mathematically, this is perfectly acceptable, and what we would
normally expect. In algebra, if we write:

-x²

we normally mean the negative of (x squared), not (negative x) squared,
which would be just x². So Python here agrees with standard mathematical
notation.
Post by D Wyatt
I am struggling with the audacity of that as -1 is negative 1,
NOT minus 1. How can an arithmetic operation trump an attribute of a
negative integer? It truly makes no sense to me. Thank you for any
enlightenment you can provide.
Speaking as a maths tutor with about 20 years experience, and a B.Sc.
with a major in mathematics, I'm not sure I understand what you are
getting at. There is no mathematical difference between the inherent
negativeness of -1 and the arithmetic operation - 1 (unary minus
operator followed by 1).

Whichever way you treat it, we have to agree what it means. For example,
2x means 2 multiplied by x; but 23 doesn't mean 2 multiplied by 3. It
could if we wanted it to, but that would be inconvenient. Mathematicians
could define -3² as (-3)² = 9 if they wanted to, but generally they
don't, although there are exceptions. Consequently such expressions are
ambiguous and are best avoided. Although -x² never means -x squared,
it always means minus (x squared).

Python removes the ambiguity and has exponentiation always take priority
over other arithmetic operators, regardless of whether you consider - a
unary or binary operator, or an inherent part of the integer.

Although, for the record, the standard Python interpreter does NOT parse
an expression like -123 as "negative 123", but as "unary minus 123". In
practice this makes zero difference to the code.
--
Steve
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Steven D'Aprano
2015-07-31 18:54:52 UTC
Permalink
Hi Deb,
I have never really thought about any of this before, but many of you
have responded like this is so obvious. That is not helpful. I'm
looking at a negative number as being an object that is one less than
zero, and the unary sign being a part of that object, glued to it.
Why is that so hard to understand?
Like many things, the behaviour here is obvious in hindsight. And you
are right, sometimes people forget that hindsight is 20:20 but foresight
is not. If I said anything that gave you the impression that your
question was a dumb question, sorry, that wasn't my intention.

In this case, your expectation that -3**2 should be treated as -3 as a
single value, raised to the power of 2, is a perfectly reasonable
expectation. I daresay that there are programming languages where that
actually is the case, and if you search the Internet, you'll find lots
of people making the same assumption as you.


Regards,


Steve
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Alan Gauld
2015-07-31 22:57:04 UTC
Permalink
I have never really thought about any of this before, but many of you
have responded like this is so obvious. That is not helpful.
That's a fair point.

In our defence I guess that many of the active "tutors" on the list are
professional programmers. And programming originated, and is often still
taught, as a branch of math. Which means we tend to have a background in
math and therefore tend to see a lot of math stuff
as "obvious" when, of course, it may not be to someone without
that background.
... when you forget that what seems obvious to you is not
obvious to everybody, you lose the ability to be as helpful as you
could be.
Again a very valid point. We try to keep our answers general and
not assume too much background. But sometimes you forget how
much you think is 'obvious' is really just
"learned a long time ago"...
The only stupid question is the question you don't ask.
And that too is true. Thanks for asking it, the discussion is
always useful and, hopefully, you will not be the only one to
benefit.
--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Continue reading on narkive:
Loading...