为什么大量的模数似乎在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

    }
}

你可以看到这个事实吗?

解决方法

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

Java中的float和double基本类型是floating point个数字,其中数字存储为分数和指数的二进制表示.

更具体地说,double-precision浮点值(例如double类型)是64位值,其中:

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

组合这些部分以产生值的双重表示.

有关如何在Java中处理浮点值的详细说明,请参阅Java语言规范的Section 4.2.3: Floating-Point Types,Formats,and Values.

byte,char,int,long类型是[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
}

相关文章

HashMap是Java中最常用的集合类框架,也是Java语言中非常典型...
在EffectiveJava中的第 36条中建议 用 EnumSet 替代位字段,...
介绍 注解是JDK1.5版本开始引入的一个特性,用于对代码进行说...
介绍 LinkedList同时实现了List接口和Deque接口,也就是说它...
介绍 TreeSet和TreeMap在Java里有着相同的实现,前者仅仅是对...
HashMap为什么线程不安全 put的不安全 由于多线程对HashMap进...