Returns n!, that is, the product of the first n positive integers, or 1 if n == 0. Warning: the result takes O(n log n) space, so use cautiously. This uses an efficient binary recursive algorithm to compute the factorial with balanced multiplies.
(int n)
| 337 | |
| 338 | |
| 339 | public static BigInteger factorial(int n) { |
| 340 | checkNonNegative("n", n); |
| 341 | |
| 342 | // If the factorial is small enough, just use LongMath to do it. |
| 343 | if (n < LongMath.factorials.length) { |
| 344 | return BigInteger.valueOf(LongMath.factorials[n]); |
| 345 | } |
| 346 | |
| 347 | // Pre-allocate space for our list of intermediate BigIntegers. |
| 348 | int approxSize = IntMath.divide(n * IntMath.log2(n, CEILING), Long.SIZE, CEILING); |
| 349 | ArrayList<BigInteger> bignums = new ArrayList<BigInteger>(approxSize); |
| 350 | |
| 351 | // Start from the pre-computed maximum long factorial. |
| 352 | int startingNumber = LongMath.factorials.length; |
| 353 | long product = LongMath.factorials[startingNumber - 1]; |
| 354 | // Strip off 2s from this value. |
| 355 | int shift = Long.numberOfTrailingZeros(product); |
| 356 | product >>= shift; |
| 357 | |
| 358 | // Use floor(log2(num)) + 1 to prevent overflow of multiplication. |
| 359 | int productBits = LongMath.log2(product, FLOOR) + 1; |
| 360 | int bits = LongMath.log2(startingNumber, FLOOR) + 1; |
| 361 | // Check for the next power of two boundary, to save us a CLZ operation. |
| 362 | int nextPowerOfTwo = 1 << (bits - 1); |
| 363 | |
| 364 | // Iteratively multiply the longs as big as they can go. |
| 365 | for (long num = startingNumber; num <= n; num++) { |
| 366 | // Check to see if the floor(log2(num)) + 1 has changed. |
| 367 | if ((num & nextPowerOfTwo) != 0) { |
| 368 | nextPowerOfTwo <<= 1; |
| 369 | bits++; |
| 370 | } |
| 371 | // Get rid of the 2s in num. |
| 372 | int tz = Long.numberOfTrailingZeros(num); |
| 373 | long normalizedNum = num >> tz; |
| 374 | shift += tz; |
| 375 | // Adjust floor(log2(num)) + 1. |
| 376 | int normalizedBits = bits - tz; |
| 377 | // If it won't fit in a long, then we store off the intermediate product. |
| 378 | if (normalizedBits + productBits >= Long.SIZE) { |
| 379 | bignums.add(BigInteger.valueOf(product)); |
| 380 | product = 1; |
| 381 | productBits = 0; |
| 382 | } |
| 383 | product *= normalizedNum; |
| 384 | productBits = LongMath.log2(product, FLOOR) + 1; |
| 385 | } |
| 386 | // Check for leftovers. |
| 387 | if (product > 1) { |
| 388 | bignums.add(BigInteger.valueOf(product)); |
| 389 | } |
| 390 | // Efficiently multiply all the intermediate products together. |
| 391 | return listProduct(bignums).shiftLeft(shift); |
| 392 | } |
| 393 | |
| 394 | |
| 395 | static BigInteger listProduct(List<BigInteger> nums) { |
nothing calls this directly
no test coverage detected