【问题标题】:Data lost from float assignment to float print从浮动分配到浮动打印的数据丢失
【发布时间】:2019-06-29 03:14:57
【问题描述】:

这是在测试期间出现的,我必须比较实际输出和预期输出之间的值。

代码:

float nf = 584227.4649743827f;
printf("Output: \t %.9f \n", nf);

输出:

Output:  584227.437500 

我在 C 方面的知识显然存在一些差距,所以有人可以向我解释一下这种情况:

  1. 为什么打印中会出现这种偏差 (0.027474382659420f)?
  2. 这只是print的限制,还是float数据类型的限制?
  3. 变量nf中实际存储了哪个值?
  4. 我应该如何使用这样的值,这样我才不会丢失诸如在分配过程中出现0.027474382659420f 偏差之类的信息。

任何其他与测试中此类问题相关的建议也将非常受欢迎。

【问题讨论】:

标签: c unit-testing floating-accuracy


【解决方案1】:

为什么打印中有这个偏差(0.027474382659420f)?

因为float的精度大约是7位,而你的偏差从第七位开始。

这只是print的限制,还是float数据类型 限制?

这是浮点数的限制,因此也包括double(尽管double 具有更高的精度)。它还与二进制数和十进制数之间的转换有关,例如0.2 是二进制表示中的重复十进制(嗯,二进制),因此也怀疑舍入错误,实际上可能变成类似0.200000000000000011.

变量nf中实际存储了哪个值?

您看到的印刷品。您指定的 584227.4649743827f 很可能甚至不会存在于已编译程序的二进制文件中,而是在编译期间“转换”为实际使用的值。

我应该如何使用这样的值,以免丢失信息 就像在分配期间有 0.027474382659420f 的偏差。

使用double,其精度约为 15-17 位。此外,您需要从584227.4649743827f 中删除f,将其转换为double 常量。如果这不够准确,您可能不得不使用外部库来代替任意精度数字,例如GMP

您的浮点数很可能符合IEEE 754 标准,但不能保证。

【讨论】:

  • “这是浮点数的限制” 这只是问题的一半。缺少的主要一点是存在十进制 -> 二进制 -> 十进制转换,并且某些数字在没有非常高或无限精度的情况下不能存在于任何一个数字系统中。
  • @user694733 好点,这会导致一些最臭名昭著的“浮点数学被破坏”类型错误,所以我对此添加了一些解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-31
  • 1970-01-01
  • 1970-01-01
  • 2013-08-20
  • 1970-01-01
  • 2012-06-10
相关资源
最近更新 更多