-1

tried multiplication of 109221975*123222821 in python 2.7 prompt in two different ways

Python 2.7.3 (default, Sep 26 2013, 20:08:41) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 109221975*123222821
13458639874691475L
>>> 109221975*123222821.0
1.3458639874691476e+16
>>> int(109221975.0*123222821.0)
13458639874691476L
>>> 109221975*123222821 == int(109221975.0*123222821.0)
False
>>> 

what I am suspecting here is that there is some precision inconsistency which is causing such problem , is it possible to speculate when can inconsistency like this happen ?

Magus
  • 123
  • 1
  • 6
  • 1
    http://docs.python.org/2/tutorial/floatingpoint.html – dm03514 Feb 19 '14 at 19:21
  • 3
    Sigh. Another day, another FP confusion. Please read [What Every Computer Scientist Should Know About Floating-Point Arithmetic](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) – dawg Feb 19 '14 at 19:22
  • 1
    There should be a warning before you post if float is anywhere in your question text to read that article first. – kylieCatt Feb 19 '14 at 19:28
  • possible duplicate of [Python rounding error with float numbers](http://stackoverflow.com/questions/5997027/python-rounding-error-with-float-numbers) – Wooble Feb 19 '14 at 19:29
  • @IanAuld: To be fair, if you actually tag the question [floating-point] you sort of do get that warning. :) – Wooble Feb 19 '14 at 19:34

3 Answers3

2

Your int is 54 bits long. float can hold 53 significant digits, so effectively the last digit is rounded to an even number.

Internally, your float is represented as:

2225720309975242*2-1

Your int and float is stored in binary like the following:

             101111110100001000111111001000111001000001000110010011
0 10000110100 0111111010000100011111100100011100100000100011001010

For float, the first part is the sign, the second is the exponent, and the third is the significand. Because space is allocated for an exponent, there isn't enough room left over for the significant digits

How I aligned the two representations, you can see the data is the same, but the int needs one extra digit on the right, while the float uses more (in this case wasted) space on the left

mhlester
  • 22,781
  • 10
  • 52
  • 75
  • For those curious, I extracted the binary of the float using `struct.unpack('Q', struct.pack('d', number))` – mhlester Feb 19 '14 at 19:36
1

Because int in python has infinite precision, but float does not. (float is a double precision floating point number, which has 53 bits of precision.)

univerio
  • 19,548
  • 3
  • 66
  • 68
1

Once upon a time, there was a string named st that wanted to be a number. What number should I be said st?

The string's fairy god mother said: Well st, if you want to be an accurate number, a number for counting whole things, I would be an arbitrary precision integer:

>>> st='123456789123456789'
>>> int(st)
123456789123456789
>>> int(st)*int(st)*int(st)
1881676377434183981909562699940347954480361860897069

'But I also want to count partial things, like the 1/2 of the sandwich I still have!' said st. So be a float said the fair godmother, but know that you may loose track of a few 1/2 sandwiches after a while. In fact, after 9007199254740992 things you may start to forget a few because you only have 53 fingers to count with when you are a float:

>>> float(int('1'*53,2)+1)
9007199254740992.0
>>> float(int('1'*53,2)+1)+1
9007199254740992.0

>>> int(float(int(st)))
123456789123456784
>>> int(st)-int(float(st))
5
dawg
  • 98,345
  • 23
  • 131
  • 206