public virtual string ToString(BigInteger intX, uint numberBase, char[] alphabet)
{
// Test base
if (numberBase < 2 || numberBase > 65536)
{
throw new ArgumentException(Strings.ToStringSmallBase, "numberBase");
}
// Special processing for zero values
if (intX._length == 0) return "0";
// Calculate output array length
uint outputLength = (uint)System.Math.Ceiling(Constants.DigitBaseLog / System.Math.Log(numberBase) * intX._length);
// Define length coefficient for string builder
bool isBigBase = numberBase > alphabet.Length;
uint lengthCoef = isBigBase ? (uint)System.Math.Ceiling(System.Math.Log10(numberBase)) + 2U : 1U;
// Determine maximal possible length of string
ulong maxBuilderLength = (ulong)outputLength * lengthCoef + 1UL;
if (maxBuilderLength > int.MaxValue)
{
// This big integer can't be transformed to string
throw new ArgumentException(Strings.IntegerTooBig, "intX");
}
// Transform digits into another base
uint[] outputArray = ToString(intX._digits, intX._length, numberBase, ref outputLength);
// Output everything to the string builder
StringBuilder outputBuilder = new StringBuilder((int)(outputLength * lengthCoef + 1));
// Maybe append minus sign
if (intX._negative)
{
outputBuilder.Append(Constants.DigitsMinusChar);
}
// Output all digits
for (uint i = outputLength - 1; i < outputLength; --i)
{
if (!isBigBase)
{
// Output char-by-char for bases up to covered by alphabet
outputBuilder.Append(alphabet[(int)outputArray[i]]);
}
else
{
// Output digits in bracets for bigger bases
outputBuilder.Append(Constants.DigitOpeningBracet);
outputBuilder.Append(outputArray[i].ToString());
outputBuilder.Append(Constants.DigitClosingBracet);
}
}
return outputBuilder.ToString();
}