0

下面的例子突出了一個陷阱相對於使用浮點數:調度事件時的時間是一個浮點值

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)。事件的持續時間會使事件相互重疊,在這種情況下,我需要通過不同的渠道發送事件。在我的代碼

+0

可能聽起來很明顯,但我認爲唯一可靠的方法是使用整數(並將單位設置爲毫秒,微秒或其他)。也許你可以縮放複雜的時間戳並將它們用作整數(如int(1000 * sin(2 * pi * f * t)')? – jdehesa 2014-08-28 08:56:27

回答

1

一個補丁修復是:

available_again = 0.1×(I + 1)

此修復程序是正確的,將讓你的代碼的工作,只要time保持足夠小對於浮點分辨率要好於0.1(最高約爲2 )。

它的工作原理是因爲在迭代i計算的浮點數0.1*(i+1)完全相同作爲計算0.1*ii的浮點數在下一迭代已經遞增一,並且因爲只要整數nm仍然低於約2 ,沒有兩個0.1*n0.1*m對於nm的不同值是相等的。

原因是浮點運算是確定性的。對於n的某些積分值,浮點運算0.1 * n可能會產生反直覺結果,但對於相同的n,它總會產生相同的結果。


如果除了它是你重要的time是最接近的數學商的i/10,那麼你應該計算timei/10.0,和邏輯,計算available_again(i+1)/10.0

這繼續出於同樣的原因按上述方式工作,並且它具有附加屬性總是計算浮點數最接近預期商數,而0.1 * i放大了浮點數0.1和之間的表示錯誤理性1/10。

在任何情況下,兩個連續值time總是以相同的間隔分隔。通過i/10.0計算,在有理i/10周圍浮點浮點值。使用0.1*i,它將在i * 0周圍浮動。1000000000000000055511151231257827021181583404541015625.如果您可以自由選擇採樣頻率,請選擇它以使itime之間的因數爲2(例如1/64或1/128)的冪。然後,您將擁有準確計算time的附加屬性,並且每個時間間隔都完全相同。

相關問題