// FactorialS computes n! given an existing swing.Swing object. // // It allows multiple factorials to be computed after computing prime numbers // just once. The swing.Swing object encapsulates a prime number sieve. // // For computing factorials up to n, the swing.Swing object should be // constructed with with the same or greater n. // // FactorialS returns nil if the sieve is not big enough. func FactorialS(z *big.Int, ps *swing.Swing, n uint) *big.Int { var oddFactorial func(*big.Int, uint) *big.Int oddFactorial = func(z *big.Int, n uint) *big.Int { if n < uint(len(swing.SmallOddFactorial)) { return z.SetInt64(swing.SmallOddFactorial[n]) } oddFactorial(z, n/2) var os big.Int return z.Mul(z.Mul(z, z), ps.OddSwing(&os, n)) } return z.Lsh(oddFactorial(z, n), n-xmath.BitCount32(uint32(n))) }
func init() { smallPiLimit = 2 for _, w := range smallComposites { smallPiLimit += uint64(32 - xmath.BitCount32(w)) } }
// SwingingFactorial member computes n≀ on a Swing object. func (ps *Swing) SwingingFactorial(z *big.Int, n uint) *big.Int { if uint64(n) > ps.Sieve.Lim { return nil } return z.Lsh(ps.OddSwing(z, n), xmath.BitCount32(uint32(n>>1))) }