Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Python incorrectly handling this "arbitrary precision integer"?

Python is supposed to have "arbitrary precision integers," according to the answer in Python integer ranges. But this result is plainly not arbitrary precision:

$ python -c 'print("%d" % (999999999999999999999999/3))'
333333333333333327740928

According to PEP 237, bignum is arbitrarily large (not just the size of C's long type). And Wikipedia says Python's bignum is arbitrary precision.

So why the incorrect result from the above line of code?

like image 776
Jeff Snider Avatar asked Jan 09 '14 21:01

Jeff Snider


People also ask

Is Python arbitrary-precision?

Generally, In low-level languages like C, the precision of integers is limited to 64-bit, but Python implements Arbitrary-precision integers.

Can Python handle large integers?

Python supports a "bignum" integer type which can work with arbitrarily large numbers. In Python 2.5+, this type is called long and is separate from the int type, but the interpreter will automatically use whichever is more appropriate.

How does Python represent integers?

Computers use binary numbers to represent integers. Python uses a variable number of bits to represent integers. Therefore, the largest integer number that Python can represent depends on the available memory of the computer. In Python, all integers are instances of the class int .

How many digits can python handle?

It handles arbitrarily large numbers of any kind. By default, it works with a precision of 28 digits, but you can change it to whatever you want, and it does change dynamically in some cases. It even has some math functions embedded, so int(decimal.


1 Answers

Actually in python3 whenever you divide ints you get float as a result. There is a // operator that does integer division:

 >>> 999999999999999999999999/3
 3.333333333333333e+23
 >>> 999999999999999999999999//3
 333333333333333333333333

 >>> type(999999999999999999999999/3)
 <class 'float'>
 >>> type(999999999999999999999999//3)
 <class 'int'>

This does give the correct arbitrary precision output:

 python -c 'print("%d" % (999999999999999999999999//3))' 
 333333333333333333333333

How to write code compatible with both python 2.2+ and 3.3

This is actually simple, just add:

 >>> from __future__ import division 

this will enable 3.X division in 2.2+ code.

>>> from sys import version 
>>> version
'2.7.6 (default, Dec 30 2013, 14:37:40) \n[GCC 4.8.2]'
>>> from __future__ import division 
>>> type(999999999999999999999999//3)
<type 'long'>
>>> type(999999999999999999999999/3)
<type 'float'>
like image 136
jb. Avatar answered Sep 24 '22 13:09

jb.