繁体   English   中英

浮点数不准确?

[英]Floating point numbers inaccuracy?

我提示用户输入一个浮点数。 我将数字保存在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

我只尝试了这件事直到10.00。

请问为什么浮点数不正确? 我知道了此行为的原因,但是没有任何办法知道哪个数字的行为会奇怪吗?

我不知道一种预测哪个数字将执行此操作的方法,但是大多数程序员并不在乎。

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

这些技术通常只是剔除数字的小数部分。 您可能要使用舍入函数。 再次,在Java中,如[javadoc]( http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html )中所述,它将为Math.round() )。

我只能告诉您不会发生哪些数字:
所有可以精确地用二进制表示的数字,即形式为所有数字:

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

要么:

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

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

使用FLT_DIG以匹配的十进制符号形式打印数字。

FLT_DIGfloat将显示的前导十进制数字的数目,并与其十进制分配的值匹配。 至少为 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在这里没有指定精度,但是可以预期<0.5百万分之一的误差。 通过许多操作,这会减少从FLT_DIG到可靠数字的数量。

通常,避免期望匹配算法和计算机结果比FLT_DIG数字更好。 如果那还不够,请使用double ,它至少对至少10位数字有效(对于典型的double ,对15位数字有利-使用DBL_DIG

注意: "%.5e"指示printf()在小数点前打印1位,在小数点后打印5位,总共6位有效数字。 这就是在printf("%.*e", FLT_DIG - 1, ...);-1的原因printf("%.*e", FLT_DIG - 1, ...);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM