有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

爪哇奇怪的地板圆整

Possible Duplicate:
Moving decimal places over in a double

我在Java中遇到了一个奇怪的问题,我有以下代码:

double velocity = -0.07;
System.out.println("raw value  " + velocity*200 );
System.out.println("floored value  " + Math.floor(velocity*200) );

我有以下输出:

raw value  -14.000000000000002
floored value  -15.0

那些轨道0002把一切都搞砸了,顺便说一句,轨道2不应该存在,我认为它应该是小数点后的所有零,我能去掉那个2吗

更新:谢谢你们的帮助,伙计们,你们知道在不调用doubleValue方法的情况下对BigDecimal对象进行地板舍入的方法吗


共 (4) 个答案

  1. # 1 楼答案

    The Floating-Point Guide

    Why don’t my numbers, like 0.1 + 0.2 add up to a nice round 0.3, and instead I get a weird result like 0.30000000000000004?

    Because internally, computers use a format (binary floating-point) that cannot accurately represent a number like 0.1, 0.2 or 0.3 at all.

    When the code is compiled or interpreted, your “0.1” is already rounded to the nearest number in that format, which results in a small rounding error even before the calculation happens.

    如果需要与特定期望值相加的数字,则不能使用double。有关详细信息,请阅读链接到站点的链接

  2. # 2 楼答案

    Java Double遵循IEEE 754浮点算法,它不能无限精确地表示每个实数。这次围捕是正常的。你不能在内部表现中摆脱它。当然可以使用字符串。格式化以打印结果

  3. # 3 楼答案

    使用BigDecimal。。。上面的问题是一个众所周知的舍入问题,在内存有限的计算机上使用表示方案。问题在于,答案在二进制(即基数2)系统中是重复的(如1/3=0.33333333…带十进制),无法正确表示。一个很好的例子是1/10=0.1,即0.000110011。。。二进制的。在某一点之后,1和0必须结束,从而导致感知错误

    希望你不是在做对生活至关重要的事情。。。例如http://www.ima.umn.edu/~arnold/disasters/patriot.html。28人因舍入错误而丧生

  4. # 4 楼答案

    因为floor(-14.000000000000002)确实是-15

    你看,floor被定义为小于或等于参数的最大整数。由于-14.000000000000002不是一个整数,向下最接近的整数是-15

    好了,现在让我们弄清楚为什么-0.07 * 200不完全是-14。这是因为浮点数的内部表示是以2为基数的,因此分母不是2幂的分数不能以100%的精度表示。(与您不能将1/3表示为小数位数有限的小数点相同。)因此velocity的值并不完全是-0.07。(当编译器看到常量-0.07时,它会用一个非常接近-0.07但实际上不等于的二进制分数悄悄地替换它。)这就是为什么velocity * 200并不完全是-14