1

We know that python float number is 64bit. And I take a test:

float(2**53) is 9007199254740992.0, 

and it is ok

float(2**53+1) is also 9007199254740992.0, 

and it is ok, because the last 1 can not be presented in 64bit binary.

float(2**53+3) is equal to float(2**53+2), 

but the result of

float(2**53+3) is **9007199254740996.0**

How does the float number work in python ?

Aswin Murugesh
  • 9,508
  • 10
  • 34
  • 65
gfish
  • 21
  • 2
  • The same way that `double` works in C. – dan04 Dec 11 '13 at 15:22
  • On my system, `float(2*53+2) == 108.0` and `float(2*53+3) == 109.0`. I suspect such overflow is undefined behavior and that you shouldn't rely on it. – Waleed Khan Dec 11 '13 at 15:23
  • 4
    [What Every Computer Scientist Should Know About Floating Point Arithmetic](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.22.6768) – devnull Dec 11 '13 at 15:24
  • 3
    @WaleedKhan, that's `**` not `*`. – Mark Ransom Dec 11 '13 at 15:24
  • 2
    [Why Do Computers Suck at Math?](http://www.codinghorror.com/blog/2009/05/why-do-computers-suck-at-math.html) – devnull Dec 11 '13 at 15:25
  • Just to round out the suggested articles, here's another take on it: http://floating-point-gui.de/ – Tim S. Dec 11 '13 at 15:28
  • 1
    @TimS., I think the poster understands that not all floating point numbers can be represented. The question is why it's rounding the way it did, and I think that's a good topic to pursue. – Mark Ransom Dec 11 '13 at 15:36

3 Answers3

1

I believe it's because you're in the default IEEE rounding mode, "round to even".

That is to say, when rounding a value exactly half way between two representable values, the result chosen is one with a 0 in the last bit of the significand.

In this case since you're losing one bit of precision, that amounts to "round to a multiple of 4".

Hence the value 9007199254740995 rounds to the representable value 9007199254740996.0, and not the equally-close and also representable value 9007199254740994.0

Meanwhile the value 9007199254740993 rounds to 9007199254740992.0, also not 9007199254740994.0.

Steve Jessop
  • 257,525
  • 32
  • 431
  • 672
0

Note that 2**53+3 is an int64, so there is no problem and if you evaluate it in python it will give you the correct answer 9007199254740995.

However, float64 has 52 bits for the fraction part, so when you convert 9007199254740995 to float64 by doing float(2**53+3), you lose precision and get rounded to a nearby number: 9007199254740996.0.

Bitwise
  • 7,043
  • 4
  • 30
  • 48
  • But why *that* particular number and not 9007199254740994.0 which is also representable? Especially when `float(9007199254740993)` returns 9007199254740992.0. – Mark Ransom Dec 11 '13 at 15:39
  • @SteveJessop, I'm not familiar enough with the rounding modes to have an answer off the top of my head, and no time at the moment to research it. – Mark Ransom Dec 11 '13 at 16:03
0

According to http://en.wikipedia.org/wiki/IEEE_floating_point IEEE standard, 64bits floats have a precision of 52 bits + 1 sign bit.

That means any number requiring more than 52 significant bits is rounded to 52 significant bits.

In your case, you have 53 significant bits, meaning the last one is discarded/rounded/something.

njzk2
  • 37,030
  • 6
  • 63
  • 102