internal static unsafe string FormatBigInteger(BigInteger value, string format, NumberFormatInfo info) { int num3; int num9; int digits = 0; char ch = ParseFormatSpecifier(format, out digits); switch (ch) { case 'x': case 'X': return(FormatBigIntegerToHexString(value, ch, digits, info)); } bool flag = ((((ch == 'g') || (ch == 'G')) || ((ch == 'd') || (ch == 'D'))) || (ch == 'r')) || (ch == 'R'); if (value._bits == null) { switch (ch) { case 'g': case 'G': case 'r': case 'R': if (digits > 0) { format = string.Format(CultureInfo.InvariantCulture, "D{0}", new object[] { digits.ToString(CultureInfo.InvariantCulture) }); } else { format = "D"; } break; } return(value._sign.ToString(format, info)); } int num2 = BigInteger.Length(value._bits); try { num3 = ((num2 * 10) / 9) + 2; } catch (OverflowException exception) { throw new FormatException(SR.GetString("Format_TooLarge"), exception); } uint[] numArray = new uint[num3]; int num4 = 0; int index = num2; while (--index >= 0) { uint uLo = value._bits[index]; for (int k = 0; k < num4; k++) { ulong num8 = NumericsHelpers.MakeUlong(numArray[k], uLo); numArray[k] = (uint)(num8 % ((ulong)0x3b9aca00L)); uLo = (uint)(num8 / ((ulong)0x3b9aca00L)); } if (uLo != 0) { numArray[num4++] = uLo % 0x3b9aca00; uLo /= 0x3b9aca00; if (uLo != 0) { numArray[num4++] = uLo; } } } try { num9 = num4 * 9; } catch (OverflowException exception2) { throw new FormatException(SR.GetString("Format_TooLarge"), exception2); } if (flag) { if ((digits > 0) && (digits > num9)) { num9 = digits; } if (value._sign < 0) { try { num9 += info.NegativeSign.Length; } catch (OverflowException exception3) { throw new FormatException(SR.GetString("Format_TooLarge"), exception3); } } } char[] chArray = new char[num9]; int startIndex = num9; for (int i = 0; i < (num4 - 1); i++) { uint num12 = numArray[i]; int num13 = 9; while (--num13 >= 0) { chArray[--startIndex] = (char)(0x30 + (num12 % 10)); num12 /= 10; } } for (uint j = numArray[num4 - 1]; j != 0; j /= 10) { chArray[--startIndex] = (char)(0x30 + (j % 10)); } if (!flag) { byte *stackBuffer = stackalloc byte[0x72]; Number.NumberBuffer buffer = new Number.NumberBuffer(stackBuffer) { sign = value._sign < 0, precision = 0x1d }; buffer.digits[0] = '\0'; buffer.scale = num9 - startIndex; int num15 = Math.Min(startIndex + 50, num9); for (int m = startIndex; m < num15; m++) { buffer.digits[m - startIndex] = chArray[m]; } return(Number.FormatNumberBuffer(buffer.PackForNative(), format, info)); } int num17 = num9 - startIndex; while ((digits > 0) && (digits > num17)) { chArray[--startIndex] = '0'; digits--; } if (value._sign < 0) { string negativeSign = info.NegativeSign; for (int n = info.NegativeSign.Length - 1; n > -1; n--) { chArray[--startIndex] = info.NegativeSign[n]; } } return(new string(chArray, startIndex, num9 - startIndex)); }
internal static string FormatBigInteger(BigInteger value, string format, NumberFormatInfo info) { int num3; int num9; char ch = ParseFormatSpecifier(format, out int digits); switch (ch) { case 'x': case 'X': return(FormatBigIntegerToHexString(value, ch, digits, info)); } bool flag = ((((ch == 'g') || (ch == 'G')) || ((ch == 'd') || (ch == 'D'))) || (ch == 'r')) || (ch == 'R'); if (!flag) { throw new FormatException("Format specifier was invalid."); } if (value._bits == null) { switch (ch) { case 'g': case 'G': case 'r': case 'R': if (digits > 0) { format = "D" + digits; } else { format = "D"; } break; } return(value._sign.ToString(format, info)); } int num2 = BigInteger.Length(value._bits); try { num3 = ((num2 * 10) / 9) + 2; } catch (OverflowException exception) { throw new FormatException("The value is too large to be represented by this format specifier.", exception); } uint[] numArray = new uint[num3]; int num4 = 0; int index = num2; while (--index >= 0) { uint uLo = value._bits[index]; for (int k = 0; k < num4; k++) { ulong num8 = NumericsHelpers.MakeUlong(numArray[k], uLo); numArray[k] = (uint)(num8 % 0x3b9aca00L); uLo = (uint)(num8 / 0x3b9aca00L); } if (uLo != 0) { numArray[num4++] = uLo % 0x3b9aca00; uLo /= 0x3b9aca00; if (uLo != 0) { numArray[num4++] = uLo; } } } try { num9 = num4 * 9; } catch (OverflowException exception2) { throw new FormatException("The value is too large to be represented by this format specifier.", exception2); } if (flag) { if ((digits > 0) && (digits > num9)) { num9 = digits; } if (value._sign < 0) { try { num9 += info.NegativeSign.Length; } catch (OverflowException exception3) { throw new FormatException("The value is too large to be represented by this format specifier.", exception3); } } } char[] chArray = new char[num9]; int startIndex = num9; for (int i = 0; i < (num4 - 1); i++) { uint num12 = numArray[i]; int num13 = 9; while (--num13 >= 0) { chArray[--startIndex] = (char)(0x30 + (num12 % 10)); num12 /= 10; } } for (uint j = numArray[num4 - 1]; j != 0; j /= 10) { chArray[--startIndex] = (char)(0x30 + (j % 10)); } int num15 = num9 - startIndex; while ((digits > 0) && (digits > num15)) { chArray[--startIndex] = '0'; digits--; } if (value._sign < 0) { string negativeSign = info.NegativeSign; for (int m = negativeSign.Length - 1; m > -1; m--) { chArray[--startIndex] = negativeSign[m]; } } return(new string(chArray, startIndex, num9 - startIndex)); }
static String FormatBigInteger(BigInteger value, String format, NumberFormatInfo info) { int digits = 0; char fmt = ParseFormatSpecifier(format, out digits); if (fmt == 'x' || fmt == 'X') { return(FormatBigIntegerToHexString(value, fmt, digits, info)); } bool decimalFmt = (fmt == 'g' || fmt == 'G' || fmt == 'd' || fmt == 'D' || fmt == 'r' || fmt == 'R'); #if SILVERLIGHT || FEATURE_NETCORE || MONO if (!decimalFmt) { // Silverlight supports invariant formats only throw new FormatException(SR.GetString(SR.Format_InvalidFormatSpecifier)); } #endif //SILVERLIGHT ||FEATURE_NETCORE || MONO if (value._bits == null) { if (fmt == 'g' || fmt == 'G' || fmt == 'r' || fmt == 'R') { if (digits > 0) { format = String.Format(CultureInfo.InvariantCulture, "D{0}", digits.ToString(CultureInfo.InvariantCulture)); } else { format = "D"; } } return(value._sign.ToString(format, info)); } // First convert to base 10^9. const uint kuBase = 1000000000; // 10^9 const int kcchBase = 9; int cuSrc = BigInteger.Length(value._bits); int cuMax; try { cuMax = checked (cuSrc * 10 / 9 + 2); } catch (OverflowException e) { throw new FormatException(SR.GetString(SR.Format_TooLarge), e); } uint[] rguDst = new uint[cuMax]; int cuDst = 0; for (int iuSrc = cuSrc; --iuSrc >= 0;) { uint uCarry = value._bits[iuSrc]; for (int iuDst = 0; iuDst < cuDst; iuDst++) { Contract.Assert(rguDst[iuDst] < kuBase); ulong uuRes = NumericsHelpers.MakeUlong(rguDst[iuDst], uCarry); rguDst[iuDst] = (uint)(uuRes % kuBase); uCarry = (uint)(uuRes / kuBase); } if (uCarry != 0) { rguDst[cuDst++] = uCarry % kuBase; uCarry /= kuBase; if (uCarry != 0) { rguDst[cuDst++] = uCarry; } } } int cchMax; try { // Each uint contributes at most 9 digits to the decimal representation. cchMax = checked (cuDst * kcchBase); } catch (OverflowException e) { throw new FormatException(SR.GetString(SR.Format_TooLarge), e); } if (decimalFmt) { if (digits > 0 && digits > cchMax) { cchMax = digits; } if (value._sign < 0) { try { // Leave an extra slot for a minus sign. cchMax = checked (cchMax + info.NegativeSign.Length); } catch (OverflowException e) { throw new FormatException(SR.GetString(SR.Format_TooLarge), e); } } } int rgchBufSize; try { // We'll pass the rgch buffer to native code, which is going to treat it like a string of digits, so it needs // to be null terminated. Let's ensure that we can allocate a buffer of that size. rgchBufSize = checked (cchMax + 1); } catch (OverflowException e) { throw new FormatException(SR.GetString(SR.Format_TooLarge), e); } char[] rgch = new char[rgchBufSize]; int ichDst = cchMax; for (int iuDst = 0; iuDst < cuDst - 1; iuDst++) { uint uDig = rguDst[iuDst]; Contract.Assert(uDig < kuBase); for (int cch = kcchBase; --cch >= 0;) { rgch[--ichDst] = (char)('0' + uDig % 10); uDig /= 10; } } for (uint uDig = rguDst[cuDst - 1]; uDig != 0;) { rgch[--ichDst] = (char)('0' + uDig % 10); uDig /= 10; } #if !SILVERLIGHT || FEATURE_NETCORE if (!decimalFmt) { // // Go to the VM for GlobLoc aware formatting // Byte *numberBufferBytes = stackalloc Byte[Number.NumberBuffer.NumberBufferBytes]; Number.NumberBuffer number = new Number.NumberBuffer(numberBufferBytes); // sign = true for negative and false for 0 and positive values number.sign = (value._sign < 0); // the cut-off point to switch (G)eneral from (F)ixed-point to (E)xponential form number.precision = 29; number.digits[0] = '\0'; number.scale = cchMax - ichDst; int maxDigits = Math.Min(ichDst + 50, cchMax); for (int i = ichDst; i < maxDigits; i++) { number.digits[i - ichDst] = rgch[i]; } fixed(char *pinnedExtraDigits = rgch) { return(Number.FormatNumberBuffer(number.PackForNative(), format, info, pinnedExtraDigits + ichDst)); } } #endif //!SILVERLIGHT ||FEATURE_NETCORE // Format Round-trip decimal // This format is supported for integral types only. The number is converted to a string of // decimal digits (0-9), prefixed by a minus sign if the number is negative. The precision // specifier indicates the minimum number of digits desired in the resulting string. If required, // the number is padded with zeros to its left to produce the number of digits given by the // precision specifier. int numDigitsPrinted = cchMax - ichDst; while (digits > 0 && digits > numDigitsPrinted) { // pad leading zeros rgch[--ichDst] = '0'; digits--; } if (value._sign < 0) { String negativeSign = info.NegativeSign; for (int i = info.NegativeSign.Length - 1; i > -1; i--) { rgch[--ichDst] = info.NegativeSign[i]; } } return(new String(rgch, ichDst, cchMax - ichDst)); }