public static FastInteger[] DecimalDigitLengthBounds(EInteger ei) { long longBitLength = ei.GetUnsignedBitLengthAsInt64(); if (longBitLength < 33) { // Can easily be calculated without estimation var fi = new FastInteger((int)ei.GetDigitCountAsInt64()); return(new FastInteger[] { fi, fi }); } else if (longBitLength <= 2135) { var bitlen = (int)longBitLength; int minDigits = 1 + (((bitlen - 1) * 631305) >> 21); int maxDigits = 1 + ((bitlen * 631305) >> 21); if (minDigits == maxDigits) { var fi = new FastInteger(minDigits); return(new FastInteger[] { fi, fi }); } else { return(new FastInteger[] { new FastInteger(minDigits), // lower bound new FastInteger(maxDigits), // upper bound }); } } else if (longBitLength <= 6432162) { var bitlen = (int)longBitLength; // Approximation of ln(2)/ln(10) int minDigits = 1 + (int)(((long)(bitlen - 1) * 661971961083L) >> 41); int maxDigits = 1 + (int)(((long)bitlen * 661971961083L) >> 41); if (minDigits == maxDigits) { var fi = new FastInteger(minDigits); return(new FastInteger[] { fi, fi }); } else { return(new FastInteger[] { new FastInteger(minDigits), // lower bound new FastInteger(maxDigits), // upper bound }); } } else { // Bit length is big enough that these bounds will // overestimate or underestimate the true base-10 digit length // as appropriate. EInteger bigBitLength = ei.GetUnsignedBitLengthAsEInteger(); EInteger lowerBound = bigBitLength.Multiply(100).Divide(335); EInteger upperBound = bigBitLength.Divide(3); return(new FastInteger[] { FastInteger.FromBig(lowerBound), // lower bound FastInteger.FromBig(upperBound), // upper bound }); } }