单精度和双精度铸造提供不同的答案

par*_*446 1 c++ floating-point casting

所以我有以下代码:

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

它给出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();
}
Run Code Online (Sandbox Code Playgroud)

它给了我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();
}
Run Code Online (Sandbox Code Playgroud)

上帝的名字在这里发生了什么?我正在使用g ++ 4.5.3进行编译.

ybu*_*ill 8

0.6不能完全以任何二进制浮点格式表示.有时它稍大一些,有点小,取决于数据类型.有关详细说明,请参阅每个程序员应了解的有关浮点运算的内容.

"内存中存储"版本不同,因为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
Run Code Online (Sandbox Code Playgroud)

  • @FailedDev:我的错,它是8087(舍入错误):) (2认同)