print(a ** b ** c) - wrong precedence order - Python - python

I tried to print(2 ** 3 ** 2) to test precedence order, but in Python then Python returned me 512.0 as result. I expected Python would take 2 first, then to the power 3 = 8. Then 8, to the power 2 returning 64 as result (since operations are read from left to the right).
But instead, Python read 2 ** 3 ** 2 = 2 ** 9 = 512 (from right to the left).
Could someone explain why did this happen?

It is described to behave that way in the docs
The power operator binds more tightly than unary operators on its left; it binds less tightly than unary operators on its right. The syntax is:
power ::= ( await_expr | primary ) ["**" u_expr]
Thus, in an unparenthesized sequence of power and unary operators, the operators are evaluated from right to left (this does not constrain the evaluation order for the operands): -1**2 results in -1.
To be pedantic your question is not about precedence in this case, but rather associativity.

Related

Why print(5 ** 2 ** 0 ** 1) = 5 in Python?

Can somebody explain me why Why print(5 ** 2 ** 0 ** 1) = 5 in Python?
I am trying to learn the language and somehow I am not quite sure how this math is done.
Thank you in advance.
Because, like many languages, the exponentiation operator binds right-to-left:
5 ** 2 ** (0 ** 1)
==
5 ** (2 ** 0)
==
5 ** 1
==
5
Exponentiation is right-associative, so your expression is the same as
5 ** (2 ** (0 ** 1))
== 5 ** (2 ** 0)
== 5 ** 1
== 5
where any integer raised to the zeroth power is 1 by definition.
Others have already pointed this out already, but I just wanted to mention the documentation. You can see this by typing help("OPERATORS") in your repl. There you will spot somewhere at the top:
Operators in the same box group left to right (except for exponentiation, which groups from right to left).
You are right to be surprised though, this seems like a very odd decision to me. In other languages, e.g. octave, 5 ^ 2 ^ 0 ^ 1 == 1 as you'd expect. Oddly enough, both Julia and R agree with python on this.
EDIT: On second thought, I suppose making exponentiation right-associative makes sense too; you would expect
to mean 5^8 rather than 25^3 ...
Incidentally, here's another trap. How much is: 5 * -1 ** 2 ? Is it 5 or -5?
See help("**") to see why it is what it is. (incidentally, this is how octave, R, and julia treat this case too).
The moral of the story is: always group when there is potential for ambiguity. Or at least check the precedence is what you think it is before ungrouping.
** is exponentiation.
0 raised to the power of 1 is 0. So, we could re-write the statement as print(5**2**0) without changing the result.
2 raised to the power of 0 is 1. So, we can re-write the statement as print(5**1) without changing the result.
5 raised to the power of 1 is 5. So, we can rewrite the statement as print(5) without changing the result.

** operator behaving differently [duplicate]

What should print (-2 ** 2) return? According to my calculations it should be 4, but interpreter returns -4.
Is this Python's thing or my math is that terrible?
According to docs, ** has higher precedence than -, thus your code is equivalent to -(2 ** 2). To get the desired result you could put -2 into parentheses
>>> (-2) ** 2
4
or use built-in pow function
>>> pow(-2, 2)
4
or math.pow function (returning float value)
>>> import math
>>> math.pow(-2, 2)
4.0
The ** operation is done before the minus. To get the results expected, you should do
print ((-2) ** 2)
From the documentation:
Thus, in an unparenthesized sequence of power and unary operators, the operators are evaluated from right to left (this does not constrain the evaluation order for the operands): -1**2 results in -1.
A full detail of operators precedence is also available in the documentation. You can see the last line is (expr) which force the expr to be evaluated before being used, hence the result of (-2) ** 2 = 4
you can also use math library...
math.pow(-2,2) --> 4
-math.pow(2,2) --> -4
math.pow(4,0.5) --> 2
Python has a problem and does not see the -2 as a number. This seems to be by design as it is mentioned in the docs.
-2 is interpreted as -(2) {unary minus to positive number 2}
That usually doesn't give a problem but in -a ** 2 the ** has higher priority as - and so with - interpreted as a unary operatoe instead of part of the number -2 ** 2 evaluates to -2 instead of 2.

Why does Python take forever to evaluate 1**4**4**4**4?

I ran into a curious issue in both Python 2 and Python 3.
>>> 1**4**4**4
1L
which seems fine, but when I do this:
>>> 1**4**4**4**4
it swamps the CPU and never finishes.
Why?
I also ran these to see if it was something with the power function, or with the ** operator and it seems to be just the ** operator.
>>> (((((1**4)**4)**4)**4)**4)
1
>>> pow(pow(pow(pow(pow(pow(1,4),4),4),4),4),4)
1
>>> pow(pow(pow(pow(pow(pow(1.0,4),4),4),4),4),4)
1.0
>>> pow(pow(pow(pow(pow(pow(1L,4),4),4),4),4),4)
1L
>>> 1L**4**4**4
1L
I also tried another language and it seems to be just Python.
Why can't it evaluate this in microseconds? Can someone explain what it's doing with the CPU time?
Is there something non-intuitive about the order of operations that I am not understanding?
With the ** operator, the binding rules are such that in unparenthesized expressions the right-hand side is evaluated first.
Your 1 ** 4 ** 4 ** 4 ** 4 is evaluated in the following order:
1 ** (4 ** (4 ** (4 ** 4)))
and it is producing and allocating the memory for the huge number on the right that takes all the time:
>>> 4 ** 4 ** 4
13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096L
>>> 4 ** 4 ** 4 ** 4
# ... wait a long time as Python allocates GBs of memory ...
Quoting the ** documentation:
Thus, in an unparenthesized sequence of power and unary operators, the operators are evaluated from right to left
Mathematically, exponentiation is right associative, so
1**4**4**4**4
is not the same as
(((((1**4)**4)**4)**4)**4)
Because it is not doing
(((((1**4)**4)**4)**4)**4)
It is doing
1**(4**(4**(4**(4**4))))
Note that the latter has to compute a HUGE number before simply raising 1 to that result.
Right associativity:
>>> 2 ** 2 ** 3
256
>>>
It's slow because it has to evaluate 4**4**4**4, which is does by multiplication to get the exact result.
(Don't forget that exponentiation is right-associative.)
P.S. 4**4**4 is 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096, so computing 4**4**4**4 by multiplication is going to take a very, very long time.

Why does Python's modulus operator (%) not match the Euclidean definition?

Euclidean definition says,
Given two integers a and b, with b ≠ 0, there exist unique integers q and r such that a = bq + r and 0 ≤ r < |b|, where |b| denotes the absolute value of b.
Based on below observation,
>>> -3 % -2 # Ideally it should be (-2 * 2) + 1
-1
>>> -3 % 2 # this looks fine, (-2 * 2) + 1
1
>>> 2 % -3 # Ideally it should be (-3 * 0) + 2
-1
looks like the % operator is running with different rules.
link1 was not helpful,
link2 gives recursive answer, because, as I do not understand how % works, it is difficult to understand How (a // b) * b + (a % b) == a works
My question:
How do I understand the behavior of modulo operator in python? Am not aware of any other language with respect to the working of % operator.
The behaviour of integer division and modulo operations are explained in an article of The History of Python, namely: Why Python's Integer Division Floors . I'll quote the relevant parts:
if one of the operands is negative, the result is floored, i.e.,
rounded away from zero (towards negative infinity):
>>> -5//2
-3
>>> 5//-2
-3
This disturbs some people, but there is a good mathematical reason.
The integer division operation (//) and its sibling, the modulo
operation (%), go together and satisfy a nice mathematical
relationship (all variables are integers):
a/b = q with remainder r
such that
b*q + r = a and 0 <= r < b
(assuming a and b are >= 0).
If you want the relationship to extend for negative a (keeping b
positive), you have two choices: if you truncate q towards zero, r
will become negative, so that the invariant changes to 0 <= abs(r)
otherwise, you can floor q towards negative infinity, and the
invariant remains 0 <= r < b.
In mathematical number theory, mathematicians always prefer the latter
choice (see e.g. Wikipedia). For Python, I made the same choice
because there are some interesting applications of the modulo
operation where the sign of a is uninteresting.
[...]
For negative b, by the way, everything just flips, and the invariant
becomes:
0 >= r > b.
In other words python decided to break the euclidean definition in certain circumstances to obtain a better behaviour in the interesting cases. In particular negative a was considered interesting while negative b was not considered as such. This is a completely arbitrary choice, which is not shared between languages.
Note that many common programming languages (C,C++,Java,...) do not satisfy the euclidean invariant, often in more cases than python (e.g. even when b is positive).
some of them don't even provide any guarantee about the sign of the remainder, leaving that detail as implementation defined.
As a side note: Haskell provides both kind of moduluses and divisions. The standard euclidean modulus and division are called rem and quot, while the floored division and "python style" modulus are called mod and div.

What is the double inequality (>>) sign in python? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Python - '>>' operator
There's some code that does this:
x = n - 1 >> 1
I don't know if I have to provide more syntax, but what does the >> mean? I've been searching all over, but can't find any explanation.
Its a shift right logical, it is a bitwise operation that tells the number to shift in bits by that amount. In this case you are shifting by 1, which is equivalent to dividing by 2.
If you do not understand bitwise operations, a simple conversion for you to remember would be this.
x >> n
is equivalent to
x // (2**n)
It is the bitwise shift-to-right operator.
It shifts the bits of the integer argument to the right by the number on the right-hand side of the expression:
>>> 8 >> 2
2
or illustrated in binary:
>>> bin(0b1000 >> 2)
'0b10'
Your code example is actually doubly confusing as it mixes arithmetic and bitwise operations. It should use the '//' integer division operation instead:
x = (n - 1) // 2
x >> y
is equivalent to
x.__rshift__(y)
which, as others have said, is meant to be a bitshift.
>> is the bitwise right shift operator. This operator move all bits in the first operand right by the second operand.
So: a >> b = a // 2**b
Example:
36 in binary is 0b100100
36 >> 1 is 0b10010 (last binary digit or "bit" is removed) which is 18
36 >> 2 is 0b1001 (2 bits removed) which is 9
Note that the operator goes after addition. So the code does n-1 first, then right shift it by 1 bit (i.e. divides by 2).

Categories

Resources