Wrong math with Python?
PythonPython 2.7MathPython Problem Overview
Just starting out with Python, so this is probably my mistake, but...
I'm trying out Python. I like to use it as a calculator, and I'm slowly working through some tutorials.
I ran into something weird today. I wanted to find out 20132013, but I wrote the wrong thing and wrote 2013013, and got this:
>>> 2013*013
22143
I checked with my calculator, and 22143 is the wrong answer! 2013 * 13 is supposed to be 26169.
Why is Python giving me a wrong answer? My old Casio calculator doesn't do this...
Python Solutions
Solution 1 - Python
Because of octal arithmetic, 013 is actually the integer 11.
>>> 013
11
With a leading zero, 013
is interpreted as a base-8 number and 181 + 380 = 11.
Note: this behaviour was changed in python 3. Here is a particularly appropriate quote from PEP 3127
> The default octal representation of integers is silently confusing to > people unfamiliar with C-like languages. It is extremely easy to > inadvertently create an integer object with the wrong value, because > '013' means 'decimal 11', not 'decimal 13', to the Python language > itself, which is not the meaning that most humans would assign to this > literal.
Solution 2 - Python
013
is an octal integer literal (equivalent to the decimal integer literal 11
), due to the leading 0.
>>> 2013*013
22143
>>> 2013*11
22143
>>> 2013*13
26169
It is very common (certainly in most of the languages I'm familiar with) to have octal integer literals start with 0
and hexadecimal integer literals start with 0x
. Due to the exact confusion you experienced, Python 3 raises a SyntaxError:
>>> 2013*013
File "<stdin>", line 1
2013*013
^
SyntaxError: invalid token
and requires either 0o
or 0O
instead:
>>> 2013*0o13
22143
>>> 2013*0O13
22143
Solution 3 - Python
Python's 'leading zero' syntax for octal literals is a common gotcha:
Python 2.7.3
>>> 010
8
The syntax was changed in Python 3.x http://docs.python.org/3.0/whatsnew/3.0.html#integers
Solution 4 - Python
This is mostly just expanding on @Wim's answer a bit, but Python indicates the base of integer literals using certain prefixes. Without a prefix, integers are interpreted as being in base-10. With an "0x", the integer will be interpreted as a hexadecimal int. The full grammar specification is here, though it's a bit tricky to understand if you're not familiar with formal grammars: http://docs.python.org/2/reference/lexical_analysis.html#integers
The table essentially says that if you want a long value (i.e. one that exceeds the capacity of a normal int), write the number followed by the letter "L" or "l"; if you want your number to be interpreted in decimal, write the number normally (with no leading 0); if you want it interpreted in octal, prefix it with "0", "0o", or "0O"; if you want it in hex, prefix it with "0x"; and if you want it in binary, prefix it with "0b" or "0B".