单精度和双精度铸造给出了不同的答案

问题描述:

所以我有以下代码:单精度和双精度铸造给出了不同的答案

#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'。 –

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