private static void ModDivCore(ref BigIntegerBuilder regNum, ref BigIntegerBuilder regDen, bool fQuo, ref BigIntegerBuilder regQuo) { regQuo.Set(0); if (regNum._iuLast < regDen._iuLast) { return; } var num1 = regDen._iuLast + 1; var num2 = regNum._iuLast - regDen._iuLast; var num3 = num2; var num4 = regNum._iuLast; while (true) { if (num4 < num2) { num3++; break; } if (regDen._bits[num4 - num2] == regNum._bits[num4]) { num4--; } else { if (regDen._bits[num4 - num2] < regNum._bits[num4]) { num3++; } break; } } if (num3 == 0) { return; } if (fQuo) { regQuo.SetSizeLazy(num3); } var num5 = regDen._bits[num1 - 1]; var num6 = regDen._bits[num1 - 2]; var num7 = NumericsHelpers.CbitHighZero(num5); var num8 = 32 - num7; if (num7 > 0) { num5 = num5 << (num7 & 31) | num6 >> (num8 & 31); num6 = num6 << (num7 & 31); if (num1 > 2) { num6 = num6 | regDen._bits[num1 - 3] >> (num8 & 31); } } regNum.EnsureWritable(); var num9 = num3; while (true) { var num10 = num9 - 1; num9 = num10; if (num10 < 0) { break; } var num = num9 + num1 > regNum._iuLast ? 0 : regNum._bits[num9 + num1]; var num11 = num; var num12 = NumericsHelpers.MakeUlong(num11, regNum._bits[num9 + num1 - 1]); var num13 = regNum._bits[num9 + num1 - 2]; if (num7 > 0) { num12 = num12 << (num7 & 63) | num13 >> (num8 & 31); num13 = num13 << (num7 & 31); if (num9 + num1 >= 3) { num13 = num13 | regNum._bits[num9 + num1 - 3] >> (num8 & 31); } } var num14 = num12 / num5; var num15 = (ulong)((uint)(num12 % num5)); if (num14 > uint.MaxValue) { num15 += num5 * (num14 - uint.MaxValue); num14 = uint.MaxValue; } while (num15 <= uint.MaxValue && num14 * num6 > NumericsHelpers.MakeUlong((uint)num15, num13)) { num14--; num15 += num5; } if (num14 > 0) { var num16 = (ulong)0; for (var i = 0; i < num1; i++) { num16 = num16 + regDen._bits[i] * num14; var num17 = (uint)num16; num16 = num16 >> 32; if (regNum._bits[num9 + i] < num17) { num16 = num16 + 1; } regNum._bits[num9 + i] = regNum._bits[num9 + i] - num17; } if (num11 < num16) { uint num18 = 0; for (var j = 0; j < num1; j++) { num18 = AddCarry(ref regNum._bits[num9 + j], regDen._bits[j], num18); } num14 = num14 - 1; } regNum._iuLast = num9 + num1 - 1; } if (fQuo) { if (num3 != 1) { regQuo._bits[num9] = (uint)num14; } else { regQuo._uSmall = (uint)num14; } } } regNum._iuLast = num1 - 1; regNum.Trim(); }
private static ReverseStringBuilder CreateBuilder(BigInteger value, NumberFormatInfo info, bool decimalFmt, int digits) { // First convert to base 10^9. const uint NumericBase = 1000000000; // 10^9 const int NumericBaseLog10 = 9; var sourceLength = Length(value.InternalBits); int maxConvertedLength; try { maxConvertedLength = checked (sourceLength * 10 / 9 + 2); } catch (OverflowException e) { throw new FormatException("The value is too large to be represented by this format specifier.", e); } var converted = new uint[maxConvertedLength]; var convertedLength = 0; for (var sourceIndex = sourceLength; --sourceIndex >= 0;) { // Take a cipher from the source var carry = value.InternalBits[sourceIndex]; // Add it to converted for (var convertedIndex = 0; convertedIndex < convertedLength; convertedIndex++) { var cipherBlock = NumericsHelpers.MakeUlong(converted[convertedIndex], carry); converted[convertedIndex] = (uint)(cipherBlock % NumericBase); carry = (uint)(cipherBlock / NumericBase); } if (carry != 0) { converted[convertedLength++] = carry % NumericBase; carry /= NumericBase; if (carry != 0) { converted[convertedLength++] = carry; } } } int stringCapacity; try { // Each uint contributes at most 9 digits to the decimal representation. stringCapacity = checked (convertedLength * NumericBaseLog10); } catch (OverflowException e) { throw new FormatException("The value is too large to be represented by this format specifier.", e); } if (decimalFmt) { if (digits > 0 && stringCapacity < digits) { stringCapacity = digits; } if (value.InternalSign < 0) { try { // Leave an extra slot for a minus sign. stringCapacity = checked (stringCapacity + info.NegativeSign.Length); } catch (OverflowException e) { throw new FormatException("The value is too large to be represented by this format specifier.", e); } } } var result = new ReverseStringBuilder(stringCapacity); for (var stringIndex = 0; stringIndex < convertedLength - 1; stringIndex++) { var cipherBlock = converted[stringIndex]; for (var cch = NumericBaseLog10; --cch >= 0;) { result.Prepend((char)('0' + cipherBlock % 10)); cipherBlock /= 10; } } for (var cipherBlock = converted[convertedLength - 1]; cipherBlock != 0;) { result.Prepend((char)('0' + cipherBlock % 10)); cipherBlock /= 10; } return(result); }