** operator behaving differently [duplicate] - python

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.

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.

print(a ** b ** c) - wrong precedence order - 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.

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 do these operators mean (** , ^ , %, //)? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
Other than the standard +, -, *and / operators; but what does these mean (** , ^ , %, //) ?
>>> 9+float(2) # addition
11.0
>>> 9-float(2) # subtraction
7.0
>>> 9*float(2) # multiplication
18.0
>>> 9/float(2) # division
4.5
>>>
>>> 9**float(2) # This looks like a square, (i.e. power 2)
81.0
>>> 9**float(3) # So ** is equivalent to `math.pow(x,p)` ?
729.0
How about the ^ operator?
>>> 9^int(2) # What is `^` in `x^u` , it only allows `int` for `u`
11
>>> 9^int(3)
10
>>> 9^int(4)
13
>>> 9^int(5)
12
>>> 9^int(6)
15
>>> 9^int(7)
14
>>> 9^int(8)
1
>>> 9^int(9)
0
>>> 9^int(10)
3
>>> 9^int(11)
2
>>> 9^int(12)
5
% in x%m returns a normal remainder modulus, but only if m < x, why is that so? What does % do?
>>> 9%float(2)
1.0
>>> 9%float(3)
0.0
>>> 9%float(4)
1.0
>>> 9%float(5)
4.0
>>> 9%float(6)
3.0
>>> 9%float(7)
2.0
>>> 9%float(8)
1.0
>>> 9%float(9)
0.0
>>> 9%float(10)
9.0
>>> 9%float(11)
9.0
>>> 9%float(12)
9.0
How about the // operator? what does it do?
>>> 9//float(2)
4.0
>>> 9//float(3)
3.0
>>> 9//float(4)
2.0
>>> 9//float(5)
1.0
>>> 9//float(6)
1.0
>>> 9//float(7)
1.0
>>> 9//float(8)
1.0
>>> 9//float(9)
1.0
>>> 9//float(1)
9.0
>>> 9//float(0.5)
18.0
**: exponentiation
^: exclusive-or (bitwise)
%: modulus
//: divide with integral result (discard remainder)
You can find all of those operators in the Python language reference, though you'll have to scroll around a bit to find them all. As other answers have said:
The ** operator does exponentiation. a ** b is a raised to the b power. The same ** symbol is also used in function argument and calling notations, with a different meaning (passing and receiving arbitrary keyword arguments).
The ^ operator does a binary xor. a ^ b will return a value with only the bits set in a or in b but not both. This one is simple!
The % operator is mostly to find the modulus of two integers. a % b returns the remainder after dividing a by b. Unlike the modulus operators in some other programming languages (such as C), in Python a modulus it will have the same sign as b, rather than the same sign as a. The same operator is also used for the "old" style of string formatting, so a % b can return a string if a is a format string and b is a value (or tuple of values) which can be inserted into a.
The // operator does Python's version of integer division. Python's integer division is not exactly the same as the integer division offered by some other languages (like C), since it rounds towards negative infinity, rather than towards zero. Together with the modulus operator, you can say that a == (a // b)*b + (a % b). In Python 2, floor division is the default behavior when you divide two integers (using the normal division operator /). Since this can be unexpected (especially when you're not picky about what types of numbers you get as arguments to a function), Python 3 has changed to make "true" (floating point) division the norm for division that would be rounded off otherwise, and it will do "floor" division only when explicitly requested. (You can also get the new behavior in Python 2 by putting from __future__ import division at the top of your files. I strongly recommend it!)
You are correct that ** is the power function.
^ is bitwise XOR.
% is indeed the modulus operation, but note that for positive numbers, x % m = x whenever m > x. This follows from the definition of modulus. (Additionally, Python specifies x % m to have the sign of m.)
// is a division operation that returns an integer by discarding the remainder. This is the standard form of division using the / in most programming languages. However, Python 3 changed the behavior of / to perform floating-point division even if the arguments are integers. The // operator was introduced in Python 2.6 and Python 3 to provide an integer-division operator that would behave consistently between Python 2 and Python 3. This means:
| context | `/` behavior | `//` behavior |
---------------------------------------------------------------------------
| floating-point arguments, Python 2 & 3 | float division | int divison |
---------------------------------------------------------------------------
| integer arguments, python 2 | int division | int division |
---------------------------------------------------------------------------
| integer arguments, python 3 | float division | int division |
For more details, see this question: Division in Python 2.7. and 3.3

Categories

Resources