コード例 #1
0
        public TResult Convert(TSource source)
        {
            if (source == null)
            {
                throw new ArgumentNullException($"{nameof(source)} can't be null.");
            }

            if (source is double)
            {
                return((TResult)(object)(IEEE754.IEEE754Format((double)(object)source)));
            }

            return((TResult)(object)source);
        }
コード例 #2
0
        public static ParseResult DoubleTryParse(char[] chars, int start, int length, out double value)
        {
            value = 0;

            if (length == 0)
            {
                return(ParseResult.Invalid);
            }

            bool isNegative = (chars[start] == '-');

            if (isNegative)
            {
                // text just a negative sign
                if (length == 1)
                {
                    return(ParseResult.Invalid);
                }

                start++;
                length--;
            }

            int   i                    = start;
            int   end                  = start + length;
            int   numDecimalStart      = end;
            int   numDecimalEnd        = end;
            int   exponent             = 0;
            ulong mantissa             = 0UL;
            int   mantissaDigits       = 0;
            int   exponentFromMantissa = 0;

            for (; i < end; i++)
            {
                char c = chars[i];
                switch (c)
                {
                case '.':
                    if (i == start)
                    {
                        return(ParseResult.Invalid);
                    }
                    if (i + 1 == end)
                    {
                        return(ParseResult.Invalid);
                    }

                    if (numDecimalStart != end)
                    {
                        // multiple decimal points
                        return(ParseResult.Invalid);
                    }

                    numDecimalStart = i + 1;
                    break;

                case 'e':
                case 'E':
                    if (i == start)
                    {
                        return(ParseResult.Invalid);
                    }
                    if (i == numDecimalStart)
                    {
                        // E follows decimal point
                        return(ParseResult.Invalid);
                    }
                    i++;
                    if (i == end)
                    {
                        return(ParseResult.Invalid);
                    }

                    if (numDecimalStart < end)
                    {
                        numDecimalEnd = i - 1;
                    }

                    c = chars[i];
                    bool exponentNegative = false;
                    switch (c)
                    {
                    case '-':
                        exponentNegative = true;
                        i++;
                        break;

                    case '+':
                        i++;
                        break;
                    }

                    // parse 3 digit
                    for (; i < end; i++)
                    {
                        c = chars[i];
                        if (c < '0' || c > '9')
                        {
                            return(ParseResult.Invalid);
                        }

                        int newExponent = (10 * exponent) + (c - '0');
                        // stops updating exponent when overflowing
                        if (exponent < newExponent)
                        {
                            exponent = newExponent;
                        }
                    }

                    if (exponentNegative)
                    {
                        exponent = -exponent;
                    }
                    break;

                default:
                    if (c < '0' || c > '9')
                    {
                        return(ParseResult.Invalid);
                    }

                    if (i == start && c == '0')
                    {
                        i++;
                        if (i != end)
                        {
                            c = chars[i];
                            if (c == '.')
                            {
                                goto case '.';
                            }
                            if (c == 'e' || c == 'E')
                            {
                                goto case 'E';
                            }

                            return(ParseResult.Invalid);
                        }
                    }

                    if (mantissaDigits < 19)
                    {
                        mantissa = (10 * mantissa) + (ulong)(c - '0');
                        if (mantissa > 0)
                        {
                            ++mantissaDigits;
                        }
                    }
                    else
                    {
                        ++exponentFromMantissa;
                    }
                    break;
                }
            }

            exponent += exponentFromMantissa;

            // correct the decimal point
            exponent -= (numDecimalEnd - numDecimalStart);

            value = IEEE754.PackDouble(isNegative, mantissa, exponent);
            return(double.IsInfinity(value) ? ParseResult.Overflow : ParseResult.Success);
        }