2011-11-01 28 views
1

所以我有以下代碼:單精度和雙精度鑄造給出了不同的答案

#include <iostream> 
int main(){ 
    float number = 0.6; 
    int anotherNumber = 20; 
    int value = (int) ((float) anotherNumber * number); 
    std::cout << value; 
    std::cin.get(); 
} 

它提供了12,像它應該考慮20 * 0.6 = 12。但是,如果我改變所有彩車雙打:

#include <iostream> 
int main(){ 
    double number = 0.6; 
    int anotherNumber = 20; 
    int value = (int) ((double) anotherNumber * number); 
    std::cout << value; 
    std::cin.get(); 
} 

它給我11代替。而爲了讓事情變得怪異,如果我更改了代碼,以便值存儲在一個變量,然後再案件後,它給出了正確的答案(12)一次。

#include <iostream> 
int main(){ 
    double number = 0.6; 
    int anotherNumber = 20; 
    double intermediate = (double) anotherNumber * number; 
    int value = (int) intermediate; 
    std::cout << value; 
    std::cin.get(); 
} 

上帝的名字在這裏發生了什麼?我正在使用g ++ 4.5.3進行編譯。

+2

除了約浮點數(這將很快我敢肯定進來),請注意,在第一種情況下,你要轉換的雙重所有平常的東西浮動。正確的浮點數字是'0.6f'。 –

回答

8

0.6不能在任何二進制浮點格式準確表示。有時候它會稍大一點,但有點小一點,這取決於數據類型。有關詳細說明,請參閱What Every Programmer Should Know About Floating-Point Arithmetic

在「在存儲器中存儲」版本不同,因爲的x87 FPU使用80位的浮點寄存器內部。

編輯:詳細的計算:

float 0.6 in memory; 
.100110011001100110011010 
loaded to register: 
.10011001100110011001101000000000000000000000000000000000000000000 
multiplied by 20: 
1100.0000000000000000000010000000000000000000000000000000000000000 
rounded down: 
1100 

double 0.6 in memory 
.10011001100110011001100110011001100110011001100110011 
loaded to register: 
.10011001100110011001100110011001100110011001100110011000000000000 
multiplied by 20: 
1011.1111111111111111111111111111111111111111111111111110000000000 
rounded down: 
1011 

double 0.6 in memory 
.10011001100110011001100110011001100110011001100110011 
loaded to register: 
.10011001100110011001100110011001100110011001100110011000000000000 
multiplied by 20: 
1011.1111111111111111111111111111111111111111111111111110000000000 
converted to double-precision and stored to memory: 
1100.0000000000000000000000000000000000000000000000000 
loaded to register: 
1100.0000000000000000000000000000000000000000000000000000000000000 
rounded down: 
1100 
+0

+1對於「8088 FPU使用80位浮點寄存器」。你怎麼可能知道這一點? :) – FailedDev

+2

@FailedDev:我的錯誤,這是8087(舍入誤差):) – ybungalobill

+0

不能給更多+1 :) – FailedDev