2013-04-05 39 views
2

在這種情況下(對象 - ,的iOS):舍入當[INT] = [浮子] + [INT]

float a = 0.99999f; 
int b = 1000; 
int c = a + b; 

在結果c = 1001。我發現它發生是因爲b轉換爲float(特定於iOS),因此a + b沒有足夠的精度來處理1000.9999和(爲什麼?)被四捨五入爲較高值。如果a0.999f,我們得到c = 1000 - 理論上正確的行爲。

所以我的問題是爲什麼浮點數四捨五入到更高的價值?描述這種行爲(或慣例)的地方?

我在iPhone Simulator,Apple LLVM 4.2編譯器上測試了這個。

+0

這裏我越來越1000. – Balu 2013-04-05 11:38:26

+0

也剛剛開始1000 – 2013-04-05 11:38:45

+0

我的錯誤,人。 'a = 0.99999f' – brigadir 2013-04-05 11:46:40

回答

4

int c = a + b中,首先將整數b轉換爲浮點數,然後再添加2個浮點數 ,並將結果截斷爲整數。

默認浮點舍入模式是FE_TONEAREST,這意味着結果添加

0.99999f + 1000f 

的 是可以被表示爲浮點數的最接近數目,這是數1001f。這個浮點數然後被截斷爲整數c = 1001

如果更改舍入模式

#include <fenv.h> 
fesetround(FE_DOWNWARD); 

然後相加的結果向下取整(約1000.99993f),你會得到c = 1000

+0

關閉,但不完全正確。用於表示浮點數加法結果的*最接近的*值類似於1001.000032(從空中拉出一個數字),所以結果四捨五入至此。然後,根據標準C規則,該數字在float-> int轉換中被截斷*爲1001。 – 2013-04-05 14:35:48

+0

@HotLicks:我不太明白。爲什麼最近的浮動點到0.99999 + 1000爲1001.000032而不是1001? 1001 *是*可表示爲浮點數,並且比1001.000032更接近1000.99999。 (在給出答案之前,我也在調試器中驗證了這一點)。 - 也許我完全錯過了某些東西? – 2013-04-05 14:48:38

+0

是的,我想你是對的 - 小整數在IEEE浮點數中完全可以表示。但需要強調的是,發生的舍入是將float值轉換爲最接近的IEEE表示,而不是舍入到整數。本質上舍入爲1001.00000,而不是1001. – 2013-04-05 16:01:40

1

原因是,當你加1000時,你會得到8位總精度的十進制數,但IEEE浮點數只支持7位數。

+0

但爲什麼這個數字是四捨五入的?外圍數字應該被切斷(就像'float' - >'int'轉換一樣)。 – brigadir 2013-04-05 12:01:43

+0

@brigadir - 實質上,總和的計算使用更高的精度,並且可以產生1000.9999932的結果。但是這不能表示爲32位浮點數。所以最接近的兩個「合法」值可能是1000.9999843和1001.0000017。在默認舍入模式下,FP單元選擇後者,因爲它更接近「真實」答案。 – 2013-04-05 14:33:11