// trailingZeros counts the number of trailing zeros in the // big.Int value. It first attempts to use an unsigned integer // representation of the big.Int to compute this because it is // roughly 8x faster. If this unsigned integer would overflow, // it falls back to formatting the big.Int itself. func trailingZeros(bi *big.Int, tmp []byte) int { if bi.BitLen() <= 64 { i := bi.Uint64() bs := strconv.AppendUint(tmp, i, 10) return trailingZerosFromBytes(bs) } bs := bi.Append(tmp, 10) return trailingZerosFromBytes(bs) }
func main() { factorial := new(big.Int).MulRange(1, 100) bytes := factorial.Append([]byte{}, 10) sum := 0 for b := range bytes { sum += int(bytes[b] - '0') } fmt.Println("sum:", sum) }
// numDigits returns the number of decimal digits that make up // big.Int value. The function first attempts to look this digit // count up in the digitsLookupTable. If the value is not there, // it defaults to constructing a string value for the big.Int and // using this to determine the number of digits. If a string value // is constructed, it will be returned so it can be used again. func numDigits(bi *big.Int, tmp []byte) (int, []byte) { if val, ok := lookupBits(bi.BitLen()); ok { if bi.Cmp(&val.border) < 0 { return val.digits, nil } return val.digits + 1, nil } bs := bi.Append(tmp, 10) return len(bs), bs }