与float和float文字相比较的奇怪输出

Ash*_*ish 34 c c++ floating-point double-precision

float f = 0.7;
if( f == 0.7 )
    printf("equal");
else
    printf("not equal");
Run Code Online (Sandbox Code Playgroud)

为什么输出not equal

为什么会这样?

hal*_*dan 50

这是因为在你的陈述中

  if(f == 0.7)
Run Code Online (Sandbox Code Playgroud)

0.7被视为双重.尝试0.7f以确保将值视为浮点数:

  if(f == 0.7f)
Run Code Online (Sandbox Code Playgroud)

但正如迈克尔在下面的评论中建议的那样,你永远不应该测试浮点值的确切相等性.

  • 也许更重要的是,不要测试浮点值的精确相等性. (17认同)
  • "不测试浮点值的相等性"仅仅基于迷信.整数溢出有一个原因.作为程序员,人们不会抛弃理性之路并宣称"尝试使用整数进行计算是无用的,它们可能会溢出".一个人学习整数如何工作以及如何正确使用它们.浮点数也是一样的.有理由说明浮点计算可能是精确的,也可能不是.原因不难理解.在某些情况下,测试平等是有意义的 (15认同)
  • 是.f后缀(如0.7f所示)使它们成为浮点字面值. (3认同)

Pas*_*uoq 14

这个答案补充了现有的答案:注意0.7不能完全表示为浮点数(或双数).如果它被准确表示,那么在转换为float然后再转换为double时不会丢失信息,并且您不会遇到此问题.

甚至可以认为应该有一个编译器警告文字浮点常量无法准确表示,特别是当标准对于是否在运行时以已设置为的模式进行舍入是如此模糊时那个时间或在另一个舍入模式的编译时.

可以精确表示的所有非整数都具有5最后一个十进制数字.不幸的是,相反的情况并非如此:有些数字5的最后一位十进制数字无法准确表示.小整数都可以被精确地表示,并且除以2的幂除以将可以表示的数字转换为可以表示的另一个数,只要你不进入非规范化数字的领域.

  • "所有可以精确表示的非整数数字都是5的最后一个小数." .每天我都学到新东西.这就是今天的事情.谢谢! (4认同)

小智 12

首先让我们看看里面的浮点数.我取0.1f它是4字节长(binary32),十六进制它是
3D CC CC CD.
通过标准IEEE 754将其转换为十进制,我们必须这样做:

在此输入图像描述
在二进制3D CC CC CD中是
0 01111011 1001100 11001100 11001101
这里第一个数字是符号位.0表示(-1)^ 0表示我们的数字是正数.
第二个8位是指数.在二进制中它是01111011 - 在十进制123中.但真实的指数是123-127(总是127)= -4,这意味着我们需要将我们得到的数字乘以2 ^( - 4).
最后23个字节是有效精度.第一位我们乘以1 /(2 ^ 1)(0.5),第二位乘以1 /(2 ^ 2)(0.25),依此类推.我们得到的是:


在此输入图像描述 在此输入图像描述

我们需要添加所有数字(2的幂)并加1(总是1,通过标准).它是
1,60000002384185791015625
现在让我们将这个数乘以2 ^( - 4),它来自Exponent.我们只是将上面的数字除以2四次:
0,100000001490116119384765625
我使用的是MS计算器


**

现在是第二部分.从十进制转换为二进制.

**
我取数字0.1
它很容易,因为没有整数部分.第一个符号位 - 它是0.指数和有效精度我现在将计算.逻辑乘以2整数(0.1*2 = 0.2),如果它大于1则减去并继续.
在此输入图像描述
数字是.00011001100110011001100110011,标准说我们必须在得到1.之前向左移动.(某事).您如何看待我们需要4个班次,从这个数字计算指数(127-4 = 123).而且现在的有效精度是
10011001100110011001100(并且丢失了位).
现在整数.符号位0指数为123(01111011),有效精度为10011001100110011001100,整数为
00111101110011001100110011001100 让我们将它与前一章的比较为
00111101110011001100110011001101
如您所见,持续位不相等.这是因为我截断了这个数字.CPU和编译器都知道,在有效精度不能保持之后,只需将最后一位设置为1即可.