0
float a = 0.7;
if(a<0.7)
  printf("true");
else
  printf("false");

OUTPUT : true

现在,如果我将 a 的值更改为 1.7 ,那么

float a = 1.7;
if(a<1.7)
  printf("true");
else
  printf("false");

OUTPUT : false

由于 0.7 被视为 double (HIGH PRECISION) 而 a 是 float (LESS PRECISION) ,因此 a < 0.7 ,在第二种情况下它应该再次相同,所以它也应该打印true。为什么这里的输出不同?

PS:我已经看过这个链接。

4

4 回答 4

5

既然您看到了对您链接的问题的回答,让我们完成它并进行必要的更改以检查您的第二种情况:


在二进制中,1.7 是:

b1.1011001100110011001100110011001100110011001100110011001100110...

但是,1.7 是一个双精度字面量,其值是 1.7 舍入到最接近的可表示双精度值,即:

b1.1011001100110011001100110011001100110011001100110011

在十进制中,这正是:

 1.6999999999999999555910790149937383830547332763671875

当您编写 float a = 1.7 时,该双精度值再次四舍五入为单精度,并且 a 获取二进制值:

b1.10110011001100110011010

这正是

 1.7000000476837158

十进制(注意它是四舍五入的!)

当您进行比较 (a < 1.7) 时,您正在将此单精度值(转换为双精度值,它不会四舍五入,因为所有单精度值都可以用双精度表示)与原始双精度值进行比较。因为

 1.7000000476837158 > 1.6999999999999999555910790149937383830547332763671875

比较正确返回 false,并且您的程序打印“false”。


好的,那么为什么 0.7 和 1.7 的结果不同呢?这一切都在四舍五入。单精度数有 24 位。当我们用二进制写下 0.7 时,它看起来像这样:

b.101100110011001100110011 00110011...

(第 24 位之后有空格来显示它的位置)。因为第 24 位之后的下一个数字是零,所以当我们四舍五入到 24 位时,我们向下舍

现在看 1.7:

b1.10110011001100110011001 10011001...

因为我们有前导1.,第 24 位的位置移动,现在第 24 位之后的下一个数字是 1,我们改为四舍五入。

于 2012-08-19T14:50:04.383 回答
4

如果floatdouble分别是 IEEE-754 32 位和 64 位浮点格式,则最接近float1.7 的是 ~1.7000000477,最接近double的是 ~1.6999999999999999556。在这种情况下,最接近的float恰好在数值上大于最接近的double

于 2012-08-19T13:56:19.730 回答
3

0.7 和 1.7 在 base-2 中的表示方式不同 - 所以一个可能比实际(精确)值略多,另一个略少。

于 2012-08-19T13:38:24.997 回答
1

这一切都与浮点的基数 2 表示有关。这是关于该主题的一个很好的参考:What Every Computer Scientist Should Know About Floating-Point Arithmetic。

于 2012-08-19T14:33:25.820 回答