浮点数- C 数据类型

4
int main() {
float a = 20000000;
float b = 1;
float c = a+b;

if (c==a) { printf("equal"); }

else { printf("not equal");}
return 0;
}

当我运行这个程序时,它会显示“equal”(相等)。 但是,当我将a的值改为2000000(少了一个零)时,答案就不正确了。 为什么?


在浮点数词汇中,当一个相对较小的值(这里是1)与一个大值相加时,完全消失的机制被称为“吸收”。 - Pascal Cuoq
4个回答

7
通常,float的精度为24位。数字20000001 = 0x1312d01需要25位才能准确表示,因此必须四舍五入。对于恰好处于两个可表示值之间的值的正常舍入模式是向最后一位零舍入,因此将20000001四舍五入为20000000作为float
2000001 = 0x1e8481需要少于24位来表示(21),因此不需要进行四舍五入。

不,2000000 = 0x1e8480。如果最后一个四位二进制数是奇数,则该数字必须为奇数。 - Daniel Fischer
你如何计算这个数字0x1312d01? - wantToLearn
@想学习 printf("%a", 20000000.f); 可能会有用——尽管当你尝试 printf("%a", 20000001.f); 时可能会感到困惑。 - Pascal Cuoq
我问了我的Haskell解释器,它比手动计算更快。但是手动计算也很简单。你从最不重要的位到最重要的位(从右到左)确定位数,如果数字是奇数,则最后一位为1,否则为0。将数字除以2(舍弃小数部分)。递归直到达到0。在C中,您可以使用“%x”格式打印十六进制无符号整数。 - Daniel Fischer
20000002 需要 25 位,但它可以完全表示为浮点数... - Mustafa Aydın

3

1

如果您声明两个变量为浮点类型,即使将这两个值设置为相同,如果您进行相等比较,您将得到不可预测的结果。有关更多详细信息,请搜索IEEE标准(IEEE 754)以表示浮点数。 维基百科文章


声称在比较相等性时会得到“不可预测的结果”,同时链接到一个解释浮点算术已于1985年标准化以实现可预测性的维基百科文章,这不是矛盾的吗? - Pascal Cuoq
@PascalCuoq,为什么文章明确解释了浮点数可能会四舍五入,但是你还要问如何和为什么呢? - user1020710


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接