Question

i am just starting with python (python3) because i read its good for the euler project since it can handle very big numbers.

now i am struggling with a quite simple problem of converting float to int. Why don't i get the same result for this:

num =  6008514751432349174082765599289028910605977570

print('num     {0} '.format(int(num)))

num = num / 2
print('num /2  {0} '.format(int(num)))

num = num * 2
print('num *2  {0} '.format(int(num)))

output for this is:

num     6008514751432349174082765599289028910605977570 
num /2  3004257375716174771611310192874715313222975488 
num *2  6008514751432349543222620385749430626445950976 
Was it helpful?

Solution

You are using float division, which cannot handle large numbers with as much precision, after which you are flooring the result by casting it back to an int().

Don't do that, that causes data loss. Use integer (floor) division with // instead:

>>> 6008514751432349174082765599289028910605977570 // 2 * 2
6008514751432349174082765599289028910605977570

This still can lead to rounding errors of course, if the input value is not divisible by 2 without flooring:

>>> 6008514751432349174082765599289028910605977571 // 2 * 2
6008514751432349174082765599289028910605977570

but floating point values are limited in precision based on your exact CPU support; see sys.float_info to see what exact limitations your platform imposes on float numbers.

On my Mac, sys.float_info.dig tells me my platform supports 15 digits of precision, but you are dividing a 46-digit integer number. This means that you throw away the bottom 30 digits from your large integer when using float division:

>>> len(str(int(6008514751432349174082765599289028910605977570 / 2) - (6008514751432349174082765599289028910605977570 // 2)))
30

That is a lot of precision loss there. :-)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top