python - 楼层划分如何根据文件规定不给出结果?

标签 python floating-point operators division floor-division

>>> print (12//0.2)
59.0
>>> print(floor(12/0.2))
60
在这种情况下,为什么楼层划分不能按规则进行?
p.s.在这种情况下,Python将0.2视为0.20000000001所以floor division生成(12/0.2000000001)59.999999...输出floor(59.999999999)但是不知道为什么python在59情况下而不是0.2情况下将0.2000000001视为floor division吗?

最佳答案

12 / 0.2产生60.0的原因不是因为对0.2的处理不同,而是因为浮点除法中的错误抵消了0.2表示中的错误。浮点数始终具有相同的值(大于十进制的0.2),但是根据操作的不同,这些错误将累积或被消除。
在其他情况下,错误不会完全消除,并显示在结果中:

>>> (12 / (0.2 * 0.2)) * 0.2
59.99999999999999
在CPython中,这些特定类型的整数除法(float//自动转换第一个参数后的float)和相对幅度的执行方式如下(有关完整方法,请参见Python's source code):
mod = a % b
result = (a - mod) / b
如果b实际上为0.2,则mod将为0,但在浮点中它会稍大一些,因此mod恰好在0.2以下。
如果您手动执行此操作,则可以看到最终结果是59.0:
>>> a = 12.0
>>> b = 0.2
>>> mod = a % b
>>> mod
0.19999999999999934
>>> (a - mod) / b
59.0
OP还询问浮点除法中的错误,这也是:
值(尾数*基数^指数):
12:         1.1000000000000000000000000000000000000000000000000000 * 2^3
0.2:        1.1001100110011001100110011001100110011001100110011010 * 2^(-3)
记住0.2不是真的0.2,而是0.200000000000000011102230246251565404236316680908203125。将12除以> 0.2的结果应为<60。
为了对这些值进行除法,我们将尾数除以指数,然后得出:
12 / 0.2:   0.1110111111111111111111111111111111111111111111111111111 * 2^6
但是最后3位不适合加倍,尾数只有53位(包括符号),而我们目前使用的是56位。
由于结果以0开头,因此我们首先进行归一化,将尾数乘以2,然后从指数中减去1。然后我们必须四舍五入到最接近的53位尾数:
normalised: 1.110111111111111111111111111111111111111111111111111111 * 2^5
rounded:    1.1110000000000000000000000000000000000000000000000000 * 2^5
1.1110000000000000000000000000000000000000000000000000000000000000 * 2 ^ 5等于60。
正确结果(1.110111111111111111111111111111111111111111111111111111111 * 2 ^ 5)与我们可以表示为64位 double 数的最接近值(1.1110000000000000000000000000000000000000000000000000000000000000 * 2 ^ 5)之差是浮点除法中的错误。

关于python - 楼层划分如何根据文件规定不给出结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64533731/

相关文章:

python - 如何在 Pyspark 中获取字符串的模

python - 在 Django 模板中创建年份下拉列表

python - 程序不进入if语句

C语言科学计数法问题

php - 2 > 10 在 PHP 中如何成立?

php - 引用-这个符号在PHP中是什么意思?

python - 状态和行动形式主义。不同类之间如何实现+,-,=运算符

python - python socket.connect超时

javascript - 解析时收集 Jinja2 标签调用

c - 如何提高浮点值的精度?