浮点数不准确?

时间:2015-04-08 14:34:00

标签: c floating-point

我提示用户输入一个浮点数。我将数字保存在float变量中并将其乘以100以使其成为整数。只允许2位小数,所以这是一件相当容易的事情。现在奇怪的是:

  1. 用户输入:0.1 - >输出:100
  2. 用户输入:1.1 - >产量:110
  3. 用户输入:1.5 - >产量:150
  4. 用户输入:2.1 - >输出:209.999985
  5. 用户输入:2.5 - >输出:250
  6. 用户输入:3.8 - >产量:380
  7. 用户输入:4.2 - >产量:419.999969
  8. 用户输入:5.6 - >产量:560
  9. 用户输入:6.0 - >产量:600
  10. 用户输入:7.5 - >产量:750
  11. 用户输入:8.1 - >产量:810.000061
  12. 用户输入:9.9 - >输出:989.999969
  13. 我试过这个东西直到10.00。

    参考Why Are Floating Point Numbers Inaccurate?我已经知道了这种行为背后的原因,但是有没有办法知道哪个数字会表现得很奇怪?

3 个答案:

答案 0 :(得分:0)

我不知道如何预测哪些数字可以做到这一点,但大多数程序员并不关心。

您没有指定正在使用的语言,但如果您想将某些内容从浮点表示更改为整数表示,则通常必须使用Double.intValue()之类的函数进行显式转换或Java中的Double.longValue()或强制转换运算符(int)double_value;

这些技巧通常只会抛弃数字的小数部分。您可能希望使用舍入函数。再次,在[javadoc](http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html

中描述的java Math.round()

答案 1 :(得分:0)

我只能告诉你哪些数字会发生:
所有数字都可以用二进制表示,即表格的所有数字:

N = Sum(i, 2^n(i))

或:

N = 2^n1 + 2^n2 + 2^n3 + ....

其中n(i)是有限范围内的整数(正数或负数)。

答案 2 :(得分:0)

使用FLT_DIG以匹配的十进制表示法打印数字。

FLT_DIG表示float将显示的前导小数位数,并与其小数指定值匹配。它位于至少 6.在下面的示例中,2.1可以打印到2.10000e+00,这是6位有效数字。 990.0可以打印到9.90000e+02,这也是6位有效数字。

printf("%.*e", FLT_DIG - 1, 2.1f);  // 2.10000e+00
printf("%.*e", FLT_DIG - 1, 990.f); // 9.90000e+02

当代码执行乘以100的操作时,float产品可能会产生舍入错误。 C在这里没有指定精度,但是<可以预期在1600万中有0.5个零件。对于许多操作,这会从FLT_DIG开始减少可靠数字。

通常,避免期望匹配算术和计算机结果比FLT_DIG数字更精细。如果这还不够,请使用double,至少10位数(至少有double),最好是15位数 - 使用DBL_DIG

注意:"%.5e"直接printf()打印前1位数字和小数点后5位数,总共6位有效数字。这就是-1

printf("%.*e", FLT_DIG - 1, ...);的原因