Java中对大数取模结果异常?阶乘尾随零计算问题咨询
double-Based Factorial Trailing Zero Calculation Fails The Root Cause: Double Precision Limits
Let’s cut straight to the chase: your problem boils down to the inherent precision limits of the double data type in Java. Here’s the breakdown:
- A
doubleuses 64 bits total, with only 52 bits dedicated to storing the actual digits (the mantissa). This means it can only represent integers exactly up to2^53(roughly 9.007 × 10¹⁵). Any integer larger than this gets stored as an approximation, not the true value. - 25! (25 factorial) is 15511210043330985984000000—a number way bigger than
2^53. When you store this in adouble, the JVM has to round it to the nearest representable value. This rounding mangles the least significant digits of the number, which is why yourfact % 10returns weird results (like 2 instead of 0). Those trailing digits you’re checking aren’t actually the real digits of 25! anymore.
The Fix: Skip Calculating the Full Factorial
You don’t need to compute the entire factorial to count trailing zeros anyway. Trailing zeros come from factors of 10, which are made by multiplying 2 and 5. Since there are always more factors of 2 than 5 in a factorial, you only need to count how many times 5 divides into the numbers from 1 to num (including multiples of 25, 125, etc.—these contribute more than one 5 each).
Here’s a corrected implementation that avoids precision issues entirely:
public class TrailingZeroes { public static void countTrailingZeros(int num) { int zeroCount = 0; // Count factors of 5, plus extra from higher powers like 25, 125 for (int i = 5; i <= num; i *= 5) { zeroCount += num / i; } System.out.println("Number of trailing zeros: " + zeroCount); } public static void main(String[] args) { countTrailingZeros(25); // Output: 6 (the correct value for 25!) } }
Let’s Verify with 25!
For 25:
- Numbers divisible by 5: 5, 10, 15, 20, 25 → 5 total.
- Numbers divisible by 25 (which add an extra 5): 25 → 1 more.
- Total trailing zeros: 5 + 1 = 6, which matches the actual value of 25!.
Why Your Brute Force Approach Fails Specifically
When you compute 25! as a double, the stored value is an approximation that loses the exact trailing zeros. The real 25! ends with six zeros, but the double version gets rounded to a number where those trailing zeros aren’t intact—so your loop stops early after counting only 1 zero.
内容的提问来源于stack exchange,提问作者Snedden27

