public long ToInt64(NumberInfo numberInfo) { if (numberInfo.radix != radix) { throw new FormatException("radix"); } ulong uInt64 = ToUInt64(numberInfo); if (numberInfo.isNegative) { if (uInt64 > PositiveInt64MinValue) { throw new OverflowException("Number out of Int64 range."); } if (uInt64 == PositiveInt64MinValue) { return(long.MinValue); } return(-(long)uInt64); } if (uInt64 > Int64MaxValue) { throw new OverflowException("Number out of Int64 range."); } return((long)uInt64); }
public static decimal ToDecimal(NumberInfo numberInfo) { if (numberInfo.radix != DecimalRadix) { throw new FormatException("decimal radix."); } if (numberInfo.exponentCount > 5) { throw new OverflowException("Exponent too big."); } if (numberInfo.integerCount + numberInfo.fractionalCount > DecimalMaxScale + 2) { throw new OverflowException("Number out of Decimal range."); } var decimalInstance = Decimal; var exponent = decimalInstance.UncheckedParse(numberInfo.chars + numberInfo.exponentBegin, numberInfo.exponentCount); if (numberInfo.exponentIsNegative) { exponent = -exponent; } var number = stackalloc uint[5]; var numberLength = 0; ToDecimalNumber(numberInfo.chars + numberInfo.integerBegin, numberInfo.integerCount, number, ref numberLength); ToDecimalNumber(numberInfo.chars + numberInfo.fractionalBegin, numberInfo.fractionalCount, number, ref numberLength); var scale = numberInfo.fractionalCount - exponent; if (scale < 0) { scale = -scale; if (scale > DecimalMaxScale - (numberInfo.integerCount + numberInfo.fractionalCount)) { throw new OverflowException("Exponent too big."); } while (scale > 0) { Mult(number, numberLength, DecimalRadix, out uint carry); if (carry != 0) { number[numberLength] = carry; ++numberLength; } --scale; } } if (numberLength > 3) { throw new OverflowException("Number out of Decimal range."); } decimal r; var upValue = (uint *)(&r); upValue[2] = number[0]; upValue[3] = number[1]; upValue[1] = number[2]; if (numberInfo.isNegative) { upValue[0] = SignMask; } if (scale != 0) { if (scale > DecimalMaxScale) { throw new OverflowException("Scale too big."); } ((byte *)upValue)[2] = (byte)scale; } return(r); }
public NumberInfo GetNumberInfo(char *chars, int length) { var r = new NumberInfo(); r.chars = chars; r.radix = radix; if (length > 0) { var index = 0; var signChar = chars[0]; switch (signChar) { case NegativeSign: case PositiveSign: ++index; r.isNegative = signChar == NegativeSign; break; } var beforeZeroCount = 0; while (index < length && chars[index] == DigitalsZeroValue) { ++beforeZeroCount; ++index; } var integerBegin = index; var integerCount = 0; while (index < length && ToRadix(chars[index]) < radix) { ++integerCount; ++index; } if (integerCount != 0) { r.integerBegin = integerBegin; r.integerCount = integerCount; } else if (beforeZeroCount != 0) { r.integerBegin = index - 1; r.integerCount = 1; } if (index < length && chars[index] == DotSign) { r.isFloat = true; ++index; var fractionalBegin = index; var fractionalCount = 0; while (index < length && ToRadix(chars[index]) < radix) { ++fractionalCount; ++index; } if (fractionalCount != 0) { for (int fractionalRight = fractionalBegin + fractionalCount - 1; fractionalRight >= 0; --fractionalRight) { if (chars[fractionalRight] != DigitalsZeroValue) { break; } --fractionalCount; } r.haveFractional = fractionalCount != 0; r.fractionalBegin = fractionalBegin; r.fractionalCount = fractionalCount; } } if (index < length) { bool haveExponent = false; switch (chars[index]) { case exponentSign: case ExponentSign: ++index; haveExponent = true; break; } if (haveExponent && index < length) { var exponentSignChar = chars[index]; switch (exponentSignChar) { case NegativeSign: case PositiveSign: ++index; r.exponentIsNegative = exponentSignChar == NegativeSign; break; } var exponentBegin = index; var exponentBeforeZeroCount = 0; while (index < length && chars[index] == DigitalsZeroValue) { ++exponentBeforeZeroCount; ++index; } var exponentCount = 0; while (index < length && ToRadix(chars[index]) < radix) { ++exponentCount; ++index; } if (exponentCount != 0) { r.exponentBegin = exponentBegin; r.exponentCount = exponentCount; } else if (beforeZeroCount != 0) { r.exponentBegin = index - 1; r.exponentCount = 1; } } } r.end = index; } return(r); }
public double ToDouble(NumberInfo numberInfo) { if (numberInfo.radix != radix) { throw new FormatException("radix"); } if (numberInfo.exponentCount > 5) { throw new OverflowException("Exponent too big."); } var exponent = UncheckedParse(numberInfo.chars + numberInfo.exponentBegin, numberInfo.exponentCount); if (numberInfo.exponentIsNegative) { exponent = -exponent; } var r = 0D; for (int i = 0, j = numberInfo.integerBegin; i < numberInfo.integerCount; ++i, ++j) { r = r * radix + ToRadix(numberInfo.chars[j]); } for (int i = 0, j = numberInfo.fractionalBegin; i < numberInfo.fractionalCount; ++i, ++j) { r = r * radix + ToRadix(numberInfo.chars[j]); } var e = (int)exponent - numberInfo.fractionalCount; var exponents = positiveExponents; if (e < 0) { exponents = negativeExponents; e = -e; } if (e > 0) { while (e >= 100) { r *= exponents[100]; e -= 100; } while (e >= 10) { r *= exponents[10]; e -= 10; } while (e >= 1) { r *= exponents[1]; --e; } } if (r > DoubleMaxPositive) { throw new OverflowException("Number out of Double range."); } return(r); }
public ulong ToUInt64(NumberInfo numberInfo) { if (numberInfo.radix != radix) { throw new FormatException("radix"); } if (numberInfo.exponentCount > 5) { throw new OverflowException("Exponent too big."); } var exponent = UncheckedParse(numberInfo.chars + numberInfo.exponentBegin, numberInfo.exponentCount); if (numberInfo.exponentIsNegative) { exponent = -exponent; } int count = ((int)exponent) + numberInfo.integerCount; if (count > uInt64NumbersLength) { throw new OverflowException("Number out of UInt64 range."); } if (count <= 0) { return(0); } byte l = 0; var c = count; var r = 0UL; for (int i = 0, j = numberInfo.integerBegin; i < numberInfo.integerCount; ++i, ++j, --c) { l = ToRadix(numberInfo.chars[j]); if (c <= 1) { goto End; } r = r * radix + l; } for (int i = 0, j = numberInfo.fractionalBegin; i < numberInfo.fractionalCount; ++i, ++j, --c) { l = ToRadix(numberInfo.chars[j]); if (c <= 1) { goto End; } r = r * radix + l; } for (; c > 1; --c) { r = r * radix; } End: if (count == uInt64NumbersLength && r > (UInt64MaxValue - l) / radix) { throw new OverflowException("Number out of UInt64 range."); } r = r * radix + l; return(r); }
public NumberInfo GetNumberInfo(char *chars, int length) { var number = new NumberInfo { integerBegin = -1, fractionalBegin = -1, exponentBegin = -1, chars = chars, radix = radix }; if (length > 0) { var index = 0; var signChar = chars[0]; switch (signChar) { case NegativeSign: case PositiveSign: ++index; number.isNegative = signChar == NegativeSign; break; } var integerBegin = index; var integerCount = 0; var integerSplitCount = 0; GetNumberCount(chars, length, ref index, ref integerCount, ref integerSplitCount); if (integerCount != 0) { SubBeginingZeroOrSplitAndEndingSplit(chars, ref integerBegin, ref integerCount, ref integerSplitCount); number.integerBegin = integerBegin; number.integerCount = integerCount; number.integerSplitCount = integerSplitCount; } if (index < length && chars[index] == DotSign) { number.isFloat = true; ++index; var fractionalBegin = index; var fractionalCount = 0; var fractionalSplitCount = 0; GetNumberCount(chars, length, ref index, ref fractionalCount, ref fractionalSplitCount); if (fractionalCount != 0) { SubBeginingSplitAndEndingZeroOrSplit(chars, ref integerBegin, ref integerCount, ref integerSplitCount); number.haveFractional = fractionalCount != 0; number.fractionalBegin = fractionalBegin; number.fractionalCount = fractionalCount; number.fractionalSplitCount = fractionalSplitCount; } } if (index < length) { bool haveExponent = false; switch (chars[index]) { case exponentSign: case ExponentSign: ++index; haveExponent = true; break; case PositiveSign: case NegativeSign: switch (chars[index - 1]) { case exponentSign: case ExponentSign: if (number.isFloat) { if (number.fractionalCount >= 2) { --number.fractionalCount; haveExponent = true; } } else if (number.integerCount >= 2) { --number.integerCount; haveExponent = true; } break; } break; } if (haveExponent && index < length) { var exponentSignChar = chars[index]; switch (exponentSignChar) { case NegativeSign: case PositiveSign: ++index; number.exponentIsNegative = exponentSignChar == NegativeSign; break; } var exponentBegin = index; var exponentCount = 0; var exponentSplitCount = 0; GetNumberCount(chars, length, ref index, ref exponentCount, ref exponentSplitCount); if (exponentCount != 0) { SubBeginingZeroOrSplitAndEndingSplit(chars, ref exponentBegin, ref exponentCount, ref exponentSplitCount); number.exponentBegin = exponentBegin; number.exponentCount = exponentCount; number.exponentSplitCount = exponentSplitCount; } } } number.end = index; } return(number); }