public bool sign; // negative sign exists public static BigNumberBuffer Create() { BigNumberBuffer number = new BigNumberBuffer(); number.digits = new StringBuilder(); return(number); }
private unsafe static Boolean NumberToBigInteger(ref BigNumberBuffer number, ref BigInteger value) { Int32 i = number.scale; Int32 cur = 0; value = 0; while (--i >= 0) { value *= 10; if (number.digits[cur] != '\0') { value += (Int32)(number.digits[cur++] - '0'); } } while (number.digits[cur] != '\0') { if (number.digits[cur++] != '0') { return(false); // disallow non-zero trailing decimal places } } if (number.sign) { value = -value; } return(true); }
private unsafe static Boolean HexNumberToBigInteger(ref BigNumberBuffer number, ref BigInteger value) { if (number.digits == null || number.digits.Length == 0) { return(false); } int len = number.digits.Length - 1; // ignore trailing '\0' byte[] bits = new byte[(len / 2) + (len % 2)]; bool shift = false; bool isNegative = false; int bitIndex = 0; // parse the string into a little-endian two's complement byte array // string value : O F E B 7 \0 // string index (i) : 0 1 2 3 4 5 <-- // byte[] (bitIndex): 2 1 1 0 0 <-- // for (int i = len - 1; i > -1; i--) { char c = number.digits[i]; byte b; if (c >= '0' && c <= '9') { b = (byte)(c - '0'); } else if (c >= 'A' && c <= 'F') { b = (byte)((c - 'A') + 10); } else { b = (byte)((c - 'a') + 10); } if (i == 0 && (b & 0x08) == 0x08) { isNegative = true; } if (shift) { bits[bitIndex] = (byte)(bits[bitIndex] | (b << 4)); bitIndex++; } else { bits[bitIndex] = isNegative ? (byte)(b | 0xF0) : (b); } shift = !shift; } value = new BigInteger(bits); return(true); }
internal unsafe static Boolean TryParseBigInteger(String value, NumberStyles style, NumberFormatInfo info, out BigInteger result) { result = BigInteger.Zero; ArgumentException e; if (!TryValidateParseStyleInteger(style, out e)) { throw e; // TryParse still throws ArgumentException on invalid NumberStyles } BigNumberBuffer bignumber = BigNumberBuffer.Create(); Byte * numberBufferBytes = stackalloc Byte[NumberPort.NumberBuffer.NumberBufferBytes]; NumberPort.NumberBuffer number = new NumberPort.NumberBuffer(numberBufferBytes); result = 0; if (!NumberPort.TryStringToNumber(value, style, ref number, bignumber.digits, info, false)) { return(false); } bignumber.precision = number.precision; bignumber.scale = number.scale; bignumber.sign = number.sign; if ((style & NumberStyles.AllowHexSpecifier) != 0) { if (!HexNumberToBigInteger(ref bignumber, ref result)) { return(false); } } else { if (!NumberToBigInteger(ref bignumber, ref result)) { return(false); } } return(true); }