internal static unsafe string NumberToString(NumberBuffer number, char format, int nMaxDigits, NumberFormatInfo info, bool isDecimal)
{
int nMinDigits = -1;
StringBuilder sb = new StringBuilder(MIN_SB_BUFFER_SIZE);
switch (format)
{
case 'C':
case 'c':
{
nMinDigits = nMaxDigits >= 0 ? nMaxDigits : info.CurrencyDecimalDigits;
if (nMaxDigits < 0)
nMaxDigits = info.CurrencyDecimalDigits;
RoundNumber(ref number, number.scale + nMaxDigits); // Don't change this line to use digPos since digCount could have its sign changed.
FormatCurrency(sb, number, nMinDigits, nMaxDigits, info);
break;
}
case 'F':
case 'f':
{
if (nMaxDigits < 0)
nMaxDigits = nMinDigits = info.NumberDecimalDigits;
else
nMinDigits = nMaxDigits;
RoundNumber(ref number, number.scale + nMaxDigits);
if (number.sign)
sb.Append(info.NegativeSign);
FormatFixed(sb, number, nMinDigits, nMaxDigits, info, null, info.NumberDecimalSeparator, null);
break;
}
case 'N':
case 'n':
{
if (nMaxDigits < 0)
nMaxDigits = nMinDigits = info.NumberDecimalDigits; // Since we are using digits in our calculation
else
nMinDigits = nMaxDigits;
RoundNumber(ref number, number.scale + nMaxDigits);
FormatNumber(sb, number, nMinDigits, nMaxDigits, info);
break;
}
case 'E':
case 'e':
{
if (nMaxDigits < 0)
nMaxDigits = nMinDigits = 6;
else
nMinDigits = nMaxDigits;
nMaxDigits++;
RoundNumber(ref number, nMaxDigits);
if (number.sign)
sb.Append(info.NegativeSign);
FormatScientific(sb, number, nMinDigits, nMaxDigits, info, format);
break;
}
case 'G':
case 'g':
{
bool enableRounding = true;
if (nMaxDigits < 1)
{
if (isDecimal && (nMaxDigits == -1))
{
// Default to 29 digits precision only for G formatting without a precision specifier
// This ensures that the PAL code pads out to the correct place even when we use the default precision
nMaxDigits = nMinDigits = DECIMAL_PRECISION;
enableRounding = false; // Turn off rounding for ECMA compliance to output trailing 0's after decimal as significant
}
else
{
// This ensures that the PAL code pads out to the correct place even when we use the default precision
nMaxDigits = nMinDigits = number.precision;
}
}
else
nMinDigits = nMaxDigits;
if (enableRounding) // Don't round for G formatting without precision
RoundNumber(ref number, nMaxDigits); // This also fixes up the minus zero case
else
{
if (isDecimal && (number.digits[0] == 0))
{
// Minus zero should be formatted as 0
number.sign = false;
}
}
if (number.sign)
sb.Append(info.NegativeSign);
FormatGeneral(sb, number, nMinDigits, nMaxDigits, info, (char)(format - ('G' - 'E')), !enableRounding);
break;
}
case 'P':
case 'p':
{
if (nMaxDigits < 0)
nMaxDigits = nMinDigits = info.PercentDecimalDigits;
else
nMinDigits = nMaxDigits;
number.scale += 2;
RoundNumber(ref number, number.scale + nMaxDigits);
FormatPercent(sb, number, nMinDigits, nMaxDigits, info);
break;
}
default:
throw new FormatException(SR.Argument_BadFormatSpecifier);
}
return sb.ToString();
}