3

I am a new user to Python 3.6.0. I am trying to divide 2 numbers that produces a big output. However, using

return ans1 // ans2

produces 55347740058143507128 while using

return int(ans1 / ans2)

produces 55347740058143506432.

Which is more accurate and why is that so?

NPE
  • 486,780
  • 108
  • 951
  • 1,012
GordonJun
  • 35
  • 4
  • You need to specify the language that you are using. – zneak Sep 08 '18 at 03:36
  • @zneak Oh thanks. Im a noob. – GordonJun Sep 08 '18 at 03:38
  • Yeah! No problem. Can you clarify which version of Python you're using, as well? Finally, could you run `repr(ans1)` and `repr(ans2)` and post the result? – zneak Sep 08 '18 at 03:38
  • @zneak Ok. I am using 3.6.0. I have printed repr(ans1) as 45159067006671175434518243598614826795313039459718126370816000000000 and repr(ans2) as 815915283247897734345611269596115894272000000000. – GordonJun Sep 08 '18 at 03:47
  • Welcome to stackoverflow. Please look at the [guide to asking a good question](https://stackoverflow.com/help/how-to-ask). Next time, be sure to tag your question with the language - most people look for questions with tags, so most of your audience will not see this question. – wordragon Sep 08 '18 at 03:49

2 Answers2

7

The first one is more accurate since it gives the exact integer result.

The second represents the intermediate result as a float. Floats have limited resolution (53 bits of mantissa) whereas the result needs 66 bits to be represented exactly. This results in a loss of accuracy.

If we looks at the hex representation of both results:

>>> hex(55347740058143507128)
'0x3001aac56864d42b8L'
>>> hex(55347740058143506432)
'0x3001aac56864d4000L'

we can see that the least-significant bits of the result that didn't fit in a 53-bit mantissa all got set to zero.

One way to see the rounding directly, without any complications brought about by division is:

>>> int(float(55347740058143507128))
55347740058143506432L
NPE
  • 486,780
  • 108
  • 951
  • 1,012
3

The flooring integer division is more accurate, in that sense.

The problem with this construction int(ans1 / ans2), is that the result is temporarily a float (before, obviously, converting it to an integer), introducing rounding to the nearest float (the amount of rounding depends on the magnitude of the number). This can even be seen by just trying to round-trip that value through a float:

print(int(float(55347740058143507128)))

Which prints 55347740058143506432. So, because plain / results in a float, that limits its accuracy.

harold
  • 61,398
  • 6
  • 86
  • 164