当时间是浮点值时调度事件

时间:2014-08-28 08:38:34

标签: python floating-point scheduling floating-accuracy floating-point-precision

以下示例突出显示了使用浮点数的缺陷:

available_again = 0
for i in range(0,15):
   time = 0.1*i

   if time < available_again:
      print("failed to schedule at " + str(time))

   available_again = time + 0.1

此代码输出以下内容:

failed to schedule at 1.3

我没想到会出现这个错误,但我确实理解为什么会这样。我有什么选择才能解决这个问题?

我的代码中有一个修复:

available_again = 0.1*(i+1) 

我想知道这是否是正确的路线。我的特定应用涉及事件的调度,其中事件发生的时间由复杂的数学函数决定,例如:sinc(2 * pi * f * t)。事件的持续时间会使事件彼此重叠,在这种情况下,我需要在不同的频道上发送它们。

1 个答案:

答案 0 :(得分:1)

  

我的代码中有一个修复:

     

available_again = 0.1 *(i + 1)

此修复是正确的,只要time保持足够小,浮点分辨率优于0.1(最多约2 50 ),您的代码就会正常工作。

这是有效的,因为在迭代0.1*(i+1)计算的浮点数i 与用0.1*i计算的浮点数完全相同 { {1}}在下一次迭代中增加了1,并且因为只要整数in保持低于约2 50 ,就没有两个{{1}对于m0.1*n的不同值,{}和0.1*m相等。

原因是浮点运算是确定性的。浮点运算n可能会为m的某些整数值产生反直觉结果,但它始终会为同一0.1 * n生成相同的结果。


另外,如果n是最接近的数学商i / 10,那么您应该将n计算为time,并在逻辑上计算time 1}}为i / 10.0

由于与上述相同的原因,它继续工作,并且它总是有额外的属性来计算最接近预期商的浮点数,而available_again放大了浮点数之间的表示错误(i+1) / 10.0和理性的1/10。

在两种情况下,0.1 * i的两个连续值始终以相同的间隔分隔。使用0.1计算,浮点值浮动在理性i / 10周围。使用time,它将漂浮在i * 0.1000000000000000055511151231257827021181583404541015625周围。如果您可以自由选择采样频率,请选择它以使i/10.00.1*i之间的系数为2的幂(例如1/64或1/128)。然后,您将拥有精确计算i的附加属性,并且每个时间间隔都完全相同。

相关问题