2013-07-02 31 views
0

對不起,不好的問題,但我認爲,我對某些變數四捨五入有問題。僅在打印時舍入值嗎?

在我的C應用程序中,我必須計算耗費的能量和傳感器節點的剩餘部分。這是每10秒計算是這樣的:

static float energy_spent = 0; 
static float remaining_energy = 1000000; 

然後每10秒的兩個值被印刷:

cycle_energy = (some long mathematical computation) 

energy_spent += cycle_energy; 
remaining_energy -= cycle_energy; 

在應用程序開始時,兩個量在初始化。由於我使用的gcc支持浮點計算,但不能打印,所以我將這兩個量轉換爲無符號長整型。

printf("Energy spent: %lu \n", (uint32_t) energy_spent); 
printf("Remaining energy: %lu \n", (uint32_t) remaining_energy); 

的問題是,在應用程序結束時,該量1000000 - energy_spent應該從它們運算出的方式等於remaining_energy

但是這在我的應用程序中並不正確。數量1000000 - energy_spentremaining_energy在開始時非常相似,但它們的差異隨時間而增加。

例如,在應用程序結束時,在一個情況下energy_spent = 207223remaining_energy = 792093,在另一個energy_spent = 215695remaining_energy = 783828

我認爲唯一的問題在於我打印的值,但我雖然只是打印值時,他們不是四捨五入。

提前致謝。

+0

帶''f'後綴的'float'例如'static float remaining_energy = 1000000.f;' –

+1

@DavidRF他爲什麼要這樣? – ouah

+0

@DavidRF你的意思是說,我的變量'remaining_energy'被初始化爲整數? – aliants

回答

0

你的問題就出在float類型本身。它沒有足夠的位來存儲你的價值。

看到這個主題:Number of significant digits for a floating point type

+0

非常感謝。這意味着,對於我的float變量等於1000000,我可以在存儲高達0.0001%的錯誤,這意味着每個週期最多1。這是浮漂的原因,是嗎? – aliants

+0

@aliants,是的。 –

1

你只是簡單地展示漂浮漂移 - 這絕對不是非常規!

的正規途徑是

static float energy_spent = 0; 
static float total_energy = 1000000; 
remaining_energy = 1000000; 

然後

energy_spent += cycle_energy; 
remaining_energy = total_energy - energy_spent; 
+0

漂浮漂移的原因是什麼?我在網上找不到任何東西。謝謝。 – aliants

+0

@aliants,原因是float沒有重要的位來存儲值,並且存在一些計算錯誤。通過許多計算,這些錯誤總結。 –

+2

如果你將舍入誤差同化爲某種分佈的白噪聲,例如在[-ulp/2,ulp/2]中對基本操作進行統一,那麼你對+ =噪聲所做的操作是累積導致你到達白噪聲的積分,一種布朗噪聲。兩個運算+ =和 - =的噪聲大多是獨立的,因此漂移(你可以預測漂移的方差,它可能像時間的平方根那樣增加) –