2013-05-31 36 views
0

我正面臨着關於舍入float和轉換爲int很奇怪的事實。math.h默認舍入模式不清除

正如這裏所說: http://www.gnu.org/software/libc/manual/html_node/Rounding.html

四捨五入到最接近的可表示值是默認的舍入模式。但它似乎不是。

所以我創造了這個簡單的程序:

#include <fenv.h> 
#include <stdio.h> 

int a; 
double b; 

main() { 
    b=1.3; a=b; printf("%f %d\n",b,a); 
    b=1.8; a=b; printf("%f %d\n",b,a); 
    b=-1.3; a=b; printf("%f %d\n",b,a); 
    b=-1.8; a=b; printf("%f %d\n",b,a); 
    printf("%d %d %d\n",fegetround(),FE_TONEAREST,FE_TOWARDZERO); 
} 

計劃與GCC-4.7(Debian的),cygwin的GCC和Visual Studio編譯。輸出相同,只有FE_TOWARDZERO的定義更改。

輸出方案:

1.300000 1 
1.800000 1 
-1.300000 -1 
-1.800000 -1 
0 0 3072 

因此,我們可以清楚地看到,該舍入模式是在所有測試的編譯器設置爲FE_TONEAREST(默認值),但所有的人都向零取整。

爲什麼?

PS:是的,我可以使用Math.round()但我想知道爲什麼會發生這種情況。

回答

0

好吧,我發現問題爲什麼會發生這種情況。 如這裏指出:

http://software.intel.com/en-us/articles/fast-floating-point-to-integer-conversions

在章

A Closer Look at Float-to-Int Conversions 

從浮點數澆鑄到32位 整數的問題從ANSI C標準,該標準規定的莖應該通過截去數字 的小數部分並保留整數結果來實現轉換 。因此,只要Microsoft Visual C++ 6.0編譯器遇到(int)或(long) 強制轉換,就會向_ftol C運行時函數插入一個調用。該函數 函數將浮點舍入模式修改爲「截斷」, 執行轉換,然後在轉換之前將舍入模式重置爲其初始狀態 。

2

因爲舍入模式適用於浮點舍入函數。轉換爲int總是截斷。

+0

我不明白。當我想旋轉浮點時,我可以使用Math.round(),ceil()或floor()。還是我看錯了? – Mihalko

+1

@Mihalko你不明白'int a =(int)aFloat;'和'int a = round(aFloat);'是不一樣的。 – 2013-05-31 07:39:18

+0

但在將浮點數轉換爲int時使用FP協處理器中的舍入模式。無論如何,我已經在這裏找到了答案:http://software.intel.com/zh-cn/articles/fast-floating-point-to-integer-conversions「章節」仔細研究浮點到整數轉換「 – Mihalko