public static UInt64 FromFixedPoint32(UInt32 mantissa, int numDigits) { // TODO: Unsigned comparison could be slightly faster, maybe return(numDigits + (Int32.MinValue + BiasedExponentMaxValue - BaseExponent) > (Int32.MinValue + BiasedExponentMaxValue) ? NativeImpl.fromFixedPointU32(mantissa, numDigits) : FromFixedPointFastUnsignedUnchecked(mantissa, numDigits)); }
public static UInt64 FromFixedPointLimitedU64(UInt64 mantissa, int numDigits) { Debug.Assert(mantissa < (1UL << 53)); return(numDigits + (Int32.MinValue + BiasedExponentMaxValue - BaseExponent) > (Int32.MinValue + BiasedExponentMaxValue) ? NativeImpl.fromFixedPoint64((Int64)mantissa, numDigits) : FromFixedPointFastUnsignedUnchecked(mantissa, numDigits)); }
public static Decimal64 FromFixedPoint(long mantissa, int numberOfDigits) { // TODO: More optimizations return(new Decimal64( 0 == (mantissa & (-1L << 53)) ? DotNetImpl.FromFixedPointLimitedU64((UInt64)mantissa, numberOfDigits) : NativeImpl.fromFixedPoint64(mantissa, numberOfDigits))); }
public Decimal64 RoundToNearestTiesAwayFromZero(Decimal64 multiple) { if (!multiple.IsFinite() || multiple.IsNonPositive()) { throw new ArgumentException("Multiple must be a positive finite number."); } if (IsNaN()) { return(this); } UInt64 ratio = NativeImpl.roundToNearestTiesAwayFromZero(NativeImpl.divide(Bits, multiple.Bits)); return(new Decimal64(NativeImpl.multiply2(ratio, multiple.Bits))); }
public Decimal64 Multiply(Decimal64 b) { return(new Decimal64(NativeImpl.multiply2(Bits, b.Bits))); }
public static Decimal ToDecimalFallback(UInt64 value) { return(new Decimal(NativeImpl.toFloat64(value))); }
public long ToLong() { return(NativeImpl.toInt64(Bits)); }
public Int64 ToFixedPoint(int numberOfDigits) { return(NativeImpl.toFixedPoint(Bits, numberOfDigits)); }
public static Decimal64 operator /(Decimal64 a, Decimal64 b) { return(new Decimal64(NativeImpl.divide(a.Bits, b.Bits))); }
public Decimal64 Divide(Decimal64 b) { return(new Decimal64(NativeImpl.divide(Bits, b.Bits))); }
public static Decimal64 operator *(Int64 a, Decimal64 b) { return(new Decimal64(NativeImpl.multiplyByInt64(b.Bits, a))); }
public static Decimal64 operator *(Decimal64 a, Int64 b) { return(new Decimal64(NativeImpl.multiplyByInt64(a.Bits, b))); }
public Decimal64 MultiplyByInteger(Int64 b) { return(new Decimal64(NativeImpl.multiplyByInt64(Bits, b))); }
public static Decimal64 operator *(Decimal64 a, Decimal64 b) { return(new Decimal64(NativeImpl.multiply2(a.Bits, b.Bits))); }
public Decimal64 Multiply(Decimal64 b, Decimal64 c, Decimal64 d) { return(new Decimal64(NativeImpl.multiply4(Bits, b.Bits, c.Bits, d.Bits))); }
public Decimal64 RoundTowardsZero() { return(new Decimal64(NativeImpl.roundTowardsZero(Bits))); }
public Decimal64 RoundToNearestTiesAwayFromZero() { return(new Decimal64(NativeImpl.roundToNearestTiesAwayFromZero(Bits))); }
public Decimal64 DivideByInteger(Int64 b) { return(new Decimal64(NativeImpl.divideByInt64(Bits, b))); }
public Decimal64 NextDown() { return(new Decimal64(NativeImpl.nextDown(Bits))); }
public static Decimal64 operator /(Decimal64 a, Int64 b) { return(new Decimal64(NativeImpl.divideByInt64(a.Bits, b))); }
public Int32 CompareTo(Decimal64 other) { return(NativeImpl.compare(Bits, other.Bits)); }
public Decimal64 MultiplyAndAdd(Decimal64 b, Decimal64 c) { return(new Decimal64(NativeImpl.multiplyAndAdd(Bits, b.Bits, c.Bits))); }
public static Decimal64 FromLong(long value) { return(new Decimal64(NativeImpl.fromInt64(value))); }
public Decimal64 ScaleByPowerOfTen(Int32 n) { return(new Decimal64(NativeImpl.scaleByPowerOfTen(Bits, n))); }
public Decimal64 Mean(Decimal64 b) { return(new Decimal64(NativeImpl.mean2(Bits, b.Bits))); }
public Decimal64 Ceiling() { return(new Decimal64(NativeImpl.roundTowardsPositiveInfinity(Bits))); }
public static UInt64 FromDecimalFallback(Decimal dec) { return(NativeImpl.fromFloat64((double)dec)); }
public Decimal64 RoundTowardsNegativeInfinity() { return(new Decimal64(NativeImpl.roundTowardsNegativeInfinity(Bits))); }
internal static UInt64 FromDecimalFloat64(Double x) { unchecked { UInt64 y = NativeImpl.fromFloat64(x); // Using signed values because unsigned division optimizations are worse than signed // in MS .NET, esp. Core2.0 while it should be opposite Int64 m; UInt64 signAndExp; UInt64 notY = ~y; if ((SpecialEncodingMask & notY) == 0) { // Special value or large coefficient if ((InfinityMask & notY) == 0) { return(y); // Infinity etc. } m = (Int64)((y & LargeCoefficientMask) + LargeCoefficientHighBits); //signAndExp = ((y << 2) & SmallCoefficientExponentMask) + (y & SignMask); signAndExp = (y & LargeCoefficientExponentMask) * 4 + (y & SignMask); if ((y & 1) != 0) { goto NeedAdjustment; } } else { // "Normal" value m = (Int64)(y & SmallCoefficientMask); // 16 digits + odd signAndExp = y & (UInt64.MaxValue << ExponentShiftSmall); if ((y & 1) != 0 && (UInt64)m > MaxCoefficient / 10 + 1) { goto NeedAdjustment; } if (0 == m) { return(Zero); } } NeedCanonize: for (Int64 n = m; ;) { Int64 mNext = n / 10; if (mNext * 10 != n) { return(signAndExp + (UInt64)n); } n = mNext; signAndExp += 1L << ExponentShiftSmall; } NeedAdjustment: // Check the last digit Int64 m1 = m + 1; m = m1 / 10; if (m1 - m * 10 > 2) { return(y); } signAndExp += 1L << ExponentShiftSmall; if (NativeImpl.toFloat64(signAndExp + (UInt64)m) != x) { return(y); } goto NeedCanonize; } }
public static Decimal64 operator -(Decimal64 a, Decimal64 b) { return(new Decimal64(NativeImpl.subtract(a.Bits, b.Bits))); }