Python 时间为浮点值时安排事件

Python 时间为浮点值时安排事件,python,floating-point,scheduling,floating-accuracy,floating-point-precision,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 我没有预料到这个错误,但我确实理解它为什么会发生。为了解决这个问题,我有哪些选择 我的代码中的一个修复方法是:

以下示例强调了使用浮点数的一个陷阱:

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
我没有预料到这个错误,但我确实理解它为什么会发生。为了解决这个问题,我有哪些选择

我的代码中的一个修复方法是:

available_again = 0.1*(i+1) 
我想知道这是不是正确的路线。我的特定应用程序涉及事件的调度,其中事件发生的时间由复杂的数学函数决定,例如:sinc(2*pi*f*t)。事件的持续时间将使得事件可能相互重叠,在这种情况下,我需要通过单独的通道发送它们

我的代码中的一个修复方法是:

available_again = 0.1*(i+1) 
再次可用=0.1*(i+1)

此修复是正确的,只要
时间
足够小,浮点分辨率优于0.1(最多约250),代码就可以正常工作

它之所以有效,是因为在迭代时计算的浮点数
0.1*(i+1)
与在下一次迭代时计算的浮点数
0.1*i
完全相同,而且因为只要整数
n
m
保持在250以下,就没有两个
0.1*n
0.1*m
对于
n
m
的不同值相等

原因是浮点运算是确定性的。浮点运算
0.1*n
可能会对
n
的某些整数值产生违反直觉的结果,但它总是对相同的
n
产生相同的结果


此外,如果
时间
是最接近的数学商i/10对您来说很重要,那么您应该将
时间
计算为
i/10.0
,并且在逻辑上,将
再次计算为
(i+1)/10.0

由于与上面相同的原因,它继续工作,并且它具有额外的属性,总是计算最接近预期商的浮点数,而
0.1*i
放大了浮点数
0.1
和有理数1/10之间的表示误差


在这两种情况下,
时间的两个连续值
总是以相同的间隔分开。通过
i/10.0
计算,浮点值在有理数i/10附近浮动。使用
0.1*i
,它将在i*0.100000000000000551151231257827021181583404541015625周围浮动。如果您可以自由选择采样频率,请选择该频率,使
i
time
之间的系数为二的幂(例如1/64或1/128)。然后你会有一个额外的属性,
时间
是精确计算的,并且每个时间间隔都是完全相同的。

听起来可能很明显,但我认为唯一可靠的方法是使用整数(并将单位设置为毫秒、微秒或其他)。也许您可以缩放复杂的时间戳并将其用作整数(比如
int(1000*sin(2*pi*f*t)
)?