Java为什么我的双数会在末尾得到数字

时间:2018-08-17 13:23:38

标签: java double

很难解释,但是就在这里。 在Java代码中,我使用了一个双精度数字,但是这个数字在不需要时最后得到的数字很小。 也许我需要使用一种更好的方法来获取剩余物。

代码如下:

public class MyClass {
  public static void main(String args[]) {
            String vRetour = "";
    Boolean valeurTrouve = false;
           double chiffre = .08 ;
    double valeurTravailDouble = 0;
    long vIntegerPart = 0;

    while (! valeurTrouve) {
        for (int i = 0; i<101;i++) {
            valeurTravailDouble = chiffre * 8;
            vIntegerPart = (long) valeurTravailDouble;

            vRetour = vRetour + vIntegerPart;
            if ((valeurTravailDouble - vIntegerPart) == 0) {
                valeurTrouve = true;
                break;
            }
            chiffre = (valeurTravailDouble - vIntegerPart);
                    System.out.println(i + " = " + chiffre);
        }
    }
}

}

问题出在最后,我要退回不需要的数字,如第1行,最后我有1。在第2行上之后,我得到了9。但是这个数字的增加和增加使我在第17行上表现不佳,因为他增加了成为我数字的一部分。

  • 0 = 0.64
  • 1 = 0.1200000000000001
  • 2 = 0.9600000000000009
  • 3 = 0.6800000000000068
  • 4 = 0.44000000000005457
  • 5 = 0.5200000000004366
  • 6 = 0.16000000000349246
  • 7 = 0.2800000000279397
  • 8 = 0.24000000022351742
  • 9 = 0.9200000017881393
  • 10 = 0.36000001430511475
  • 11 = 0.880000114440918
  • 12 = 0.04000091552734375
  • 13 = 0.32000732421875
  • 14 = 0.56005859375
  • 15 = 0.48046875
  • 16 = 0.84375
  • 17 = 0.75

怎么了,在不保留数字结尾的情况下如何处理双精度?

3 个答案:

答案 0 :(得分:0)

众所周知,Java无法正确地“添加”。您应该尝试在代码中更早地舍入数字并限制小数位,以防止出现错误。在完成计算之前,请使用import java.math.BigDecimal进行四舍五入。

有关如何舍入此其他帖子的信息: Java BigDecimal: Round to the nearest whole value

答案 1 :(得分:0)

这不是Java的问题。通常,这是计算机中浮点数的硬件表示问题。 Java并没有向您“隐藏”这一事实。

表示形式分为两部分。螳螂和指数。

FP编号然后表示为M * 2 ^ E

现在设想此表示形式中的数字0.1,限于3位(2 +符号)。代表的最小片段是2 ^ -3,即0.128。因此,表示0.1的尝试最终得到0.128。对于计算机,精确度要大得多,这仍然有限。这样您可以得到较小的差异。

为了证明更大的差异,现在假设将0.1 * 10转换为“我们的4位指数表示,我们得到0.128 * 10 = 1.28!

这是计算机中FP编号的普遍问题。这就是为什么不推荐它的原因使用a == b

比较FP编号

答案 2 :(得分:0)

这是工作代码:

   while (! valeurTrouve) {
        for (int i = 0; i<101;i++) {
            valeurTravailDouble = java.math.BigDecimal.valueOf(chiffre * 8).setScale(5, java.math.RoundingMode.HALF_UP).doubleValue();
                        System.out.println(i + " :: " + valeurTravailDouble);
            vIntegerPart = (int) valeurTravailDouble;

            vRetour = vRetour + vIntegerPart;

            if ((valeurTravailDouble - vIntegerPart) == 0) {
                valeurTrouve = true;
                break;
            }
            chiffre = java.math.BigDecimal.valueOf((valeurTravailDouble - vIntegerPart)).setScale(5, java.math.RoundingMode.HALF_UP).doubleValue();
                    System.out.println(i + " = " + chiffre);
        }
    }

我使用的精度为5,但也许我不得不使用3。