floating point values comparison failure
在C语言中,如果我们执行以下代码:
1 2 3 4 5 6 7 8 9
| float a = 0.7;
if (a < 0.7)
{
printf("Less");
}
else
{
printf("no");
} |
上面的代码打印"更少"。
但如果我们执行以下代码:
1 2 3 4 5 6 7 8 9
| float a = 1.7;
if (a < 1.7)
{
printf("Less");
}
else
{
printf("no");
} |
号
它印着"不"。
原因是什么?float数据类型是如何工作的?
- 您可能需要查找"浮点舍入错误"-有很多关于这些问题的文章:-)
- a必须阅读-docs.oracle.com/cd/e19957-01/806-3568/ncg_goldberg.html
- 正如你在这里看到的,它也用C++ 11打印得更少。请参阅Luchian的链接了解原因。
- 如果你真的想比较浮动文字,在它后面加上f,就像23.6f一样。
- 如=100/3=33.3333……同样地,当你用二进制转换0.7时,你会得到一个无限(或长)的0、1序列,这就是四字节float.7f的原因!=8字节的double0.7。请记住,不固定的浮点文本是双精度的,舍入意味着即使是小的文本在舍入为浮点和双精度时也可以具有不同的值。
问题是,a是float,而0.7是double。分配给a的值从double转换为float,这会降低精度。当你把a与double作比较时,a被扩大到double的范围,但精度已经丧失,它们可能不再相等。
如果您将0.7和1.7改为0.7f和1.7f,那么它们将被转换为float文本,并且在这两种情况下都将可靠地与a相比较。
float数据类型使用近似值。C/C++中的每个数值数据类型都使用有限的固定字节来存储值。float以指数格式存储值,这样,如果将另一种格式的值传递给它,该值将被四舍五入…然后,如果你看到小数点后足够多的数字,你肯定会看到非零值。正如彼得·亚历山大在回答中所说,以东十一〔十二〕不是一个"纯"的浮动值。
进一步详细解释这种设计背后的动机对于一个用户来说可能太长了——但是如果你谷歌搜索的话,你可能会阅读更多关于这方面的内容。其中一位评论人,Luchian,在那里留下了一个很好的链接:http://docs.oracle.com/cd/e19957-01/806-3568/ncg_goldberg.html