Esempio n. 1
0
 public static UInt64 FromDecimalFallback(Decimal dec)
 {
     return(NativeImpl.fromFloat64((double)dec));
 }
Esempio n. 2
0
        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;
            }
        }
Esempio n. 3
0
 public static Decimal64 FromDouble(Double value)
 {
     return(new Decimal64(NativeImpl.fromFloat64(value)));
 }