楼层划分操作员的结果存在差异

Ken*_*ers 0 python python-3.x

我发现今天的楼层划分有些奇怪:

>>> 10.1/1.01
10.0
>>> 10.1//1.01
9.0

>>> 2688937/268893.7
10.0
>>> 2688937//268893.7
9.0

>>> 6.6/3.3
2.0
>>> 6.6//3.3
2.0
Run Code Online (Sandbox Code Playgroud)

我认为这是由于浮点错误引起的,但我想知道是否还有其他一些原因会使10.0下降到9.0。

Ant*_*ala 6

您可以使用以下函数使用字符串格式检查浮点数的精确十进制扩展format

>>> format(10.1, '.70f')
'10.0999999999999996447286321199499070644378662109375000000000000000000000'
>>> format(1.01, '.70f')
'1.0100000000000000088817841970012523233890533447265625000000000000000000'
Run Code Online (Sandbox Code Playgroud)

它是突然很清晰:二进制尾数最接近10.1 略小的量小于该确切的数字,而最接近于1.01稍微超过确切。

但是,实际结果10.1 / 1.01是四舍五入至10.0 准确的,因为一个是价值最接近除法运算的结果

>>> format(10.1 / 1.01, '.f')
'10.0000000000000000000000000000000000000000000000000000000000000000000000'
Run Code Online (Sandbox Code Playgroud)

但地板师第一向下,再向下楼的整数。

更具体地说,float.__floordiv__在CPython调用中float_divmod,该调用又使用fmodC标准库函数来查找除法的浮点余数。fmodC标准库中的描述是

描述

  1. fmod函数计算的浮点余x/y

退货

  1. fmod函数返回值x - ny,对于某些整数n,使得如果y不为零,则结果具有相同的符号x和幅度小于的幅度y。如果y为零,fmod则实现定义域错误或函数返回零。

fmod函数math.fmod在CPython标准库中可用。


的结果math.fmod(10.1, 1.01)

>>> format(math.fmod(10.1, 1.01), '.70f')
'1.0099999999999995647925743469386361539363861083984375000000000000000000'
Run Code Online (Sandbox Code Playgroud)

如果从中减去该值,10.1并将结果四舍五入为最接近的精确整数,则得到9