首页 > 解决方案 > 为什么大量模数似乎在Java中给出了错误的答案

问题描述

我正在尝试在数字中查找尾随零的数字,这是我的代码:

public class TrailingZeroes {
    public static void  bruteForce(int num){ //25
        double fact = num; //25
        int numOfZeroes = 0;

        for(int i= num - 1; i > 1; i--){
            fact = fact * (i);
        }
        System.out.printf("Fact: %.0f\n",fact); //15511210043330984000000000

        while(fact % 10 == 0){
          fact = fact / 10;
          double factRem = fact % 10;
          System.out.printf("Fact/10: %.0f\n",fact); //1551121004333098400000000
            System.out.printf("FactRem: %.0f\n",factRem); // 2?
          numOfZeroes++;
        }

        System.out.println("Nnumber of zeroes "+ numOfZeroes); //1

    }
}

如您所见%10

标签: java

解决方案


您非法使用浮点数据类型。

Java 中的floatdouble原始类型是浮点数,其中数字存储为分数和指数的二进制表示。

更具体地说,类型等双精度浮点值double是 64 位值,其中:

  • 1 位表示符号(正或负)。
  • 11 位为指数。
  • 有效数字为 52 位(小数部分为二进制)。

这些部分组合起来产生一个double值的表示。

有关如何在 Java 中处理浮点值的详细说明,请参阅第 4.2.3 节:Java 语言规范的浮点类型、格式和值

, byte, char,类型intlong[fixed-point][6] 数字,它们是数字的精确表示。与定点数不同,浮点数有时(可以安全地假设“大部分时间”)无法返回数字的精确表示。这就是为什么你最终11.399999999999得到5.6 + 5.8.

当需要一个精确的值(例如 1.5 或 150.1005)时,您需要使用其中一种能够精确表示数字的定点类型。

正如已经多次提到的,Java 有一个BigDecimal类可以处理非常大的数字和非常小的数字。


public static void bruteForce(int num) {    //25
    double fact = num;

    // precision was lost on high i
    for (int i = num - 1; i > 1; i--)
        fact *= i;

    String str = String.format("%.0f", fact);   //15511210043330984000000000
    System.out.println(str);

    int i = str.length() - 1;
    int numOfZeroes = 0;

    while (str.charAt(i--) == '0')
        numOfZeroes++;

    System.out.println("Number of zeroes " + numOfZeroes);  //9
}

推荐阅读