How does Python evaluate the expression 1+++2?
How many ever + I put in between, it is printing 3 as the answer. Please can anyone explain this behavior
And for 1--2 it is printing 3 and for 1---2 it is printing -1
Your expression is the same as:
1+(+(+2))
Any numeric expression can be preceded by - to make it negative, or + to do nothing (the option is present for symmetry). With negative signs:
1-(-(2)) = 1-(-2)
= 1+2
= 3
and
1-(-(-2)) = 1-(2)
= -1
I see you clarified your question to say that you come from a C background. In Python, there are no increment operators like ++ and -- in C, which was probably the source of your confusion. To increment or decrement a variable i or j in Python use this style:
i += 1
j -= 1
The extra +'s are not incrementors (like ++a or a++ in c++). They are just showing that the number is positive.
There is no such ++ operator. There is a unary + operator and a unary - operator though. The unary + operator has no effect on its argument. The unary - operator negates its operator or mulitplies it by -1.
+1
-> 1
++1
-> 1
This is the same as +(+(1))
1+++2
-> 3
Because it's the same as 1 + (+(+(2))
Likewise you can do --1 to mean - (-1) which is +1.
--1
-> 1
For completeness there is no * unary opeartor. So *1 is an error. But there is a **
operator which is power of, it takes 2 arguments.
2**3
-> 8
1+(+(+2)) = 3
1 - (-2) = 3
1 - (-(-2)) = -1
Trying Unary Plus and Unary minus:
The unary - (minus) operator yields the negation of its numeric argument.
The unary + (plus) operator yields its numeric argument unchanged.
>>> +2
2
>>> ++2
2
>>> +++2
2
>>> -2
-2
>>> --2
2
>>> ---2
-2
>>> 1+(++2)
3
I believe it's being parsed as, the first + as a binary operation (add), and the rest as unary operations (make positive).
1 + (+(+2))
Think it as 1 + (+1*(+1*2))). The first + is operator and following plus signs are sign of second operand (= 2).
Just like 1---2 is same as 1 - -(-(2)) or 1- (-1*(-1*(2))
Related
I have two expressions like given below:
a,b,c=2,4,5
print(a|b*c)
output : 22
How it is returning me the 22
and second expression is :
print(a|b^c)
output : 3
Can anyone please explain to me how python calculating this? I am a newbie in python I don't know how it is calculating this.
print(a|b*c)
Because of the operator precedence, the multiplication (*) will be processed before the bitwise OR (|), so the operations will happen in the following order:
b*c = 4*5 = 20
a|b*c = 2|20, i.e 10 OR 10100 = 10110 in binary
That gives us a final answer of 22.
print(a|b^c)
Likewise, due to the operator precedence, the bitwise XOR (ˆ) will be processed first, so we'll have:
bˆc = 4ˆ5, i.e 100 XOR 101 = 001 in binary
a|bˆc = 2|1, i.e 10 OR 01 = 11 in binary
That gives us a final answer of 3.
EXPRESSION # 1
Lets consider,
a|b*c
Precedence of * (multiplication) is greater than | (bitwise OR) thats why first b*c will be computed and then its output will be computed with a
STEPS:
1- b*c will return 20.
2- Then a will perform bit wise OR operation with b*c. See Bitwise OR operation ( OR returns 1 when there is any one else 0)
3- Convert values of a and b*c to binary and perform bitwise operation. See Convert decimal to binary
1 0 > a = 2
1 0 1 0 0 > b*c = 20
_________
1 0 1 1 0 > a|b*c = 22
EXPRESSION # 2
Lets consider,
a|b^c
Precedence of ^ (bitwise XOR) is greater than | (bitwise OR) thats why first b^c will be computed and then its output will be computed with a
STEPS:
1- Bitwise XOR operation will be performed between b and c (b^c). See Bitwise XOR operation ( XOR returns 1 when there are odd number of ones else 0)
1 0 0 > b = 4
1 0 1 > c = 5
______
0 0 1 > b^c = 1
2- Then a will perform bit wise OR operation with b^c. See Bitwise OR operation ( OR returns 1 when there is any one else 0)
1 0 > a =2
0 1 > b^c = 1
___
1 1 > a|b^c = 3
You need to break down the numbers into their binary representation to see what's happening under the hood.
Case 1,
Binary for a (2) - 00010
Binary for b*c (20) - 10100
So if you do a bitwise OR (|) you'll get a binary sum of above two i.e. 10110 = 22
Case 2,
Binary for a (2) - 00010
Binary for b (4) - 00100
Binary for c (5) - 00101
Again if you do a bitwise XOR (^) you'll get a binary exclusive or of b and c i.e. 00001= 1
Finally if you do a bitwise OR (|) you'll get a binary sum of a with b^c i.e. 00011 = 3
This is doing a mix of bitwise and integer arithmetic operations.
How does that work?
Based on the order of precedence of operators defined in the docs, the first expression to be evaluated is b*c, which returns 20. Then we evaluate the expression a|20. This is a bitwise operation on the two integers, so what we are doing is doing a logical OR on each bit of the binary representation of these two numbers i.e. (00010) | (10100) which gives us (10110) i.e. 22
Similarly, in the second example, we first do XOR on b and c, which is equal to 1 (calculated as binary 100 XOR 101 = 001). The result is then bitwise ORed with a, returning the value 3
The Precedence of arithmetic operators *, / , +, - is more than
bitwise operators &, |, ^ and both types of operators are evaluated left to right if the same precedence is found.
Moreover,
for arithmetic operator precedence order is : *,/ then +,-
and for bitwise operator precedence order is: & , ^, |
Check this article for more information
Coming to the solution:
The first expression evaluates like this: a|(b*c)
The second expression evaluates like this: a|(b^c)
This question already has answers here:
Calculation error with pow operator
(4 answers)
Closed 5 years ago.
This prints -2.4:
print(-3**0.8)
But this prints an imaginary number...?
a = -3
b = 0.8
print(a**b)
I can't figure out what is causing this and this problem is breaking my program. How do you make it so that the second statement outputs the same as the first in a general case that works for positive and negative values for a?
Per the Python 3.6 documentation:
6.5. The power operator
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.
Thus, in the first example:
>>> -3 ** 0.8
-2.4082246852806923
It's evaluated right to left as ** has higher precedence than unary -, binding tighter -- so here, 3 ** 0.8 is evaluated first, then the unary - operator is applied for a negative value. In the second example however, the expression is equivalent (-3) ** 0.8 as -3 is stored in a name, and evaluation results is an imaginary number:
>>> a = -3
>>> b = 0.8
>>> a ** b
(-1.9482946966653392+1.4155189542146738j)
A solution would be to calculate the result without unary operators, then applying a sign as necessary, per Shakar Bhattarai's answer:
>>> int(a / abs(a)) * (abs(a) ** b)
-2.4082246852806923
The first part, int(a / abs(a)) evaluates to either -1.0 or 1.0 depending on if a is negative or not, basically applying the sign. It then multiplies that by the result of a ** b regardless of a's sign. That will first compute a ** b disregarding it's sign, then applying the sign as necessary. This will get rid of the discrepancy. You could apply the same concept with math.copysign:
>>> math.copysign(1, a) * (abs(a) ** b)
-2.4082246852806923
This will just copy the sign from a to 1, which will give -1.0 or 1.0 based on negativity.
This is because of the precedence of the power operator. The power operator binds tighter than unary operators. So:
-3 ** 0.8
is evaluated as
-(3 * 0.8)
You can see how Python parses your code using the ast module:
>>> import ast
>>> ast.dump(ast.parse('-3 ** 0.8'))
'Module(body=[Expr(value=UnaryOp(op=USub(), operand=BinOp(left=Num(n=3), op=Pow(), right=Num(n=0.8))))])'
>>>
In the above, the 3 ** 0.8 is treated as one expression with ** being the operator. The unary minus is then applied to the value of the inner expression.
However, in your second example the values are stored in variables, so the precedence does not affect the expression. So a ** b is equivlent to (-3) ** 0.8
The solution is to bind the unary minus to the three using parenthesis:
>>> (-3) ** 0.8
(-1.94829469666534+1.4155189542146727j)
>>>
The ** operator has the highest precedence over all other operators. Hence when you use
print(-3**0.8)
python first evaluates the exponential and then negates it.
But when you run
a = -3
b = 0.8
print(a**b)
a has implicitly been negated first. Hence the result is effectively a imaginary number (a negative number raised to a fractional exponent)
To solve your issue, you could do something like
print (int(a/abs(a))*(abs(a)**b))
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.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 9 years ago.
Improve this question
I'm confused with the logic of 1% 2 will be 1. Because from what I know 1/2 is 0 so there is no remainder for this.
1/2 is 0 with a remainder of 1. The % operator returns that remainder.
% returns the remainder of a / b:
>>> 1 % 2
1
>>> 1/2
0
>>> 1 - 0
1
Also, the modulo expression can be expressed as:
r = a - nq
Where q is floor(a/n). So:
>>> import math
>>> 1 - 2 * math.floor(1/2)
1.0
% is the modulo operator. It returns the remainder after dividing the left hand side by the right hand side. Since 2 divides zero times into 1, the remainder is one.
In general, if a and b are positive integers, and a < b, then a % b == a.
The arguments do not need to be integers, though. More detail is available from the python reference documentation (http://docs.python.org/2/reference/expressions.html):
The % (modulo) operator yields the remainder from the division of the first argument by the second. The numeric arguments are first converted to a common type. A zero right argument raises the ZeroDivisionError exception. The arguments may be floating point numbers, e.g., 3.14%0.7 equals 0.34 (since 3.14 equals 4*0.7 + 0.34.) The modulo operator always yields a result with the same sign as its second operand (or zero); the absolute value of the result is strictly smaller than the absolute value of the second operand [2].
The integer division and modulo operators are connected by the following identity: x == (x/y)*y + (x%y). Integer division and modulo are also connected with the built-in function divmod(): divmod(x, y) == (x/y, x%y). These identities don’t hold for floating point numbers; there similar identities hold approximately where x/y is replaced by floor(x/y) or floor(x/y) - 1 [3].
Certainly there is a remainder. How many 2s can you get out of 1? 0 of them, with 1 left over.
Ok, the answer has been posted like 6 times already, just adding this for completeness, If there's one way to understand modulo (%), it's converting from base 10 to base 2, 1 can't be divided by 2 so we leave it alone (get a remainder of 1). You can imagine the binary numbers in the third column to be the results of a modulo operation.
eg. 9 (base 10) to (base 2)..
2 | 9 | 1
2 | 4 | 0
2 | 2 | 0
2 | 1 | 1
2*0 is 0
hence the remainder is 1
if the question is to find m%n
we find smallest or equal q such that n*(some whole number) = q and q<=m
we then find (m-q) which is the remainder..
What the % operator is doing:
a % b equals a value c such as 0 <= c < b and there exists a number k so that b * k + c = a.
I "accidentally" came across this weird but valid syntax
i=3
print i+++i #outputs 6
print i+++++i #outputs 6
print i+-+i #outputs 0
print i+--+i #outputs 6
(for every even no: of minus symbol, it outputs 6 else 0, why?)
Does this do anything useful?
Update (Don't take it the wrong way..I love python):
One of Python's principle says
There should be one-- and preferably only one --obvious way to do it. It seems there are infinite ways to do i+1
Since Python doesn't have C-style ++ or -- operators, one is left to assume that you're negating or positivating(?) the value on the left.
E.g. what would you expect i + +5 to be?
i=3
print i + +(+i) #outputs 6
print i + +(+(+(+i))) #outputs 6
print i + -(+i) #outputs 0
print i + -(-(+i)) #outputs 6
Notably, from the Python Grammar Specification, you'll see the line:
factor: ('+'|'-'|'~') factor | power
Which means that a factor in an expression can be a factor preceded by +, -, or ~. I.e. it's recursive, so if 5 is a factor (which it is because factor->power->NUMBER), then -5 is a factor and so are --5 and --------5.
The plus signs are considered unary operators to the right most i variable, as in +(-3) = -3, or +(+(+3))) = 3. Just the left most sign (plus or minus) are parsed as binary, so i+++i = i + (+(+i)), which translates to i + i = 3 + 3 = 6, in your example.
The other expressions follow the same principle.
That should read
print i + (+ (+i) )
that is, the first sign is the addition operator, the other ones are infix signs
+i
and (unfortunately)
++i
are thus valid statements.