从topLanguage看到的:http://groups.google.com/group/pongba/browse_thread/thread/9361e17333282db8?hl=zh-CN

很有意思的

题目描述:

#include <iostream>

int main()
{
float a = 1000.43;
float b = 1000.0;
std::cout << a – b << ‘\n’;
//…
}

g++和vc的输出都是 0.429993

我认为比较好的回答:

#include <iostream>
#include <bitset>
#include <iomanip>
using namespace std;

void outputBits(const char *pName, float f)
{
bitset<32> bs = *(int*)&f;
cout << pName << ” : ” << bs.to_string() << endl;

}

void output(const char *pName, float f)
{
cout << pName << ” : ” << setprecision(30) <<  f << endl;

}

int main()
{
float a = 1000.43f;
float b = 1000.0f;
output(“a”, a);
outputBits(“a”, a);
output(“b”, b);
outputBits(“b”, b);

a -= b;
float c = 0.43f;

output(“a”, a);
outputBits(“a”, a);
output(“c”, c);
outputBits(“c”, c);

}

在vc上输出
a : 1000.4299926757812
a : 01000100011110100001101110000101
b : 1000
b : 01000100011110100000000000000000
a : 0.42999267578125
a : 00111110110111000010100000000000
c : 0.43000000715255737
c : 00111110110111000010100011110110

0.43本来就不能精确表示成2的幂之和
输出a能够显示1000.43是因为打印的时候也只能近似打印
做差过后, 结果的有效位被截断3log2(10)位, 因为浮点的表示方式, 会自动对其尾数减小阶码, 造成不精确部分放大, 而且是移位放大,
会和直接赋值的0.43的位模式不同是肯定的
如果结果(如0.43)能够在float或double的尾数位中能精确的表示, 那么肯定做差和直接赋值位模式相同, 输出也相同
如果不能精确表示, 由于移位放大的缘故, 肯定就会和直接赋值的位模式不同, 最终输出结果是否一致就取决于输出精度, 如果输出精度小, 二者输出结果相同,
否则精度越大越能呈现出二者位模式不同的真相
二进制实现和十进制语法不匹配的结果

本文地址:http://www.yaronspace.cn/blog/index.php/archives/217

来自yaronspace.cn  本文链接:http://yaronspace.cn/blog/archives/217