简体   繁体   中英

Difference between floor function and floor division

Why is the answer not same for the below operations, and also, since // is essentially floor division, then why is the output different when a floor function is used.

I ran the following code:

import math
x = 2**64 -1
print("Original value:", x)
print("Floor division:", x//1)
print("Floor function:", math.floor(x/1))
print("Trunc function:", math.trunc(x/1))
print("Type conversion:", int((x/1)))

Output:

Original value: 18446744073709551615
Floor division: 18446744073709551615
Floor function: 18446744073709551616
Trunc function: 18446744073709551616
Type conversion: 18446744073709551616

Now, why is the answer not equal to the original value since all i did was divide by 1?

float is a 64 bit IEEE-754 binary floating point value; it only has 53 bits of integer precision (beyond which it's stuck with imprecise approximations based on multiplying an integer value by a power of 2), and you put a 64 bit value in there when you divided by 1 (which coerced to a float result before the eventual call to round / trunc ). Basically, it made the float value as close to the int you used as possible, which was unfortunately not equal to the int (because that's impossible), then rounded/truncated it (which, given the value had no decimal component, just meant converting back to the equivalent int value).

Floor division with // never has the problem, because it's a purely int -based division (nothing is ever represented as a float ), and int s are (to the limits of computer memory) effectively infinite precision.

/ converts to float. And float arithmetic has inherent numerical errors. As soon as you input x/1 you potentially introduce errors on the original value of x . Once the error is there you basically can't recover it.

This is broader than just an integer flooring issue:

x = 2**70 + 123
print(x-int(x/1))

123

Conversions to integer can unmask inaccuracies in a floating-point number. For example, the closest single-precision floating-point number to 21.33 is slightly less than 21.33, so when it is multiplied by 100, the result Y is slightly less than 2133.0.

If you print Y in a typical floating-point format, rounding causes it to be displayed as 2133.00. However, if you assign Y to an integer I, no rounding is done, and the number is truncated to 2132.

Also, as @shadowRanger said, // represents integer division and hence is precise till infinite.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM