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.