简体   繁体   English

楼层功能与楼层划分的区别

[英]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?现在,为什么答案不等于原始值,因为我所做的只是除以 1?

float is a 64 bit IEEE-754 binary floating point value; float是 64 位 IEEE-754 二进制浮点值; 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 ).它只有 53 位的整数精度(除此之外,它被困在基于将整数值乘以 2 的幂的不精确近似值),并且当您除以1时将一个 64 位值放入其中(这会强制为float结果)在最终调用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).基本上,它使float值尽可能接近您使用的int ,不幸的是它不等于int (因为这是不可能的),然后四舍五入/截断它(鉴于该值没有小数部分,只是意味着转换回到等效的int值)。

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.使用//楼层除法从来没有问题,因为它是一个纯粹基于int的除法(没有任何东西表示为float ),并且int s(在计算机内存的限制下)实际上是无限精度。

/ 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 .一旦您输入x/1您就有可能在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.例如,最接近 21.33 的单精度浮点数略小于 21.33,所以乘以 100 时,结果 Y 略小于 2133.0。

If you print Y in a typical floating-point format, rounding causes it to be displayed as 2133.00.如果以典型的浮点格式打印 Y,四舍五入会使其显示为 2133.00。 However, if you assign Y to an integer I, no rounding is done, and the number is truncated to 2132.但是,如果将 Y 分配给整数 I,则不会进行四舍五入,并且该数字会被截断为 2132。

Also, as @shadowRanger said, // represents integer division and hence is precise till infinite.此外,正如@shadowRanger 所说, //代表整数除法,因此精确到无限。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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