Example #1
0
        public static String FormatDecimal(Decimal value, String format, IFormatProvider provider)
        {
            NumberFormatInfo info = provider == null ? NumberFormatInfo.CurrentInfo : NumberFormatInfo.GetInstance(provider);

            NumberBuffer number = new NumberBuffer();

            DecimalToNumber(value, ref number);

            int  digits;
            char fmt = ParseFormatSpecifier(format, out digits);
            ValueStringBuilder sb;

            unsafe
            {
                char *stackPtr = stackalloc char[CharStackBufferSize];
                sb = new ValueStringBuilder(new Span <char>(stackPtr, CharStackBufferSize));
            }
            if (fmt != 0)
            {
                NumberToString(ref sb, ref number, fmt, digits, info, true);
            }
            else
            {
                NumberToStringFormat(ref sb, ref number, format, info);
            }
            return(sb.GetString());
        }
Example #2
0
        public static String FormatSingle(float value, String format, IFormatProvider provider)
        {
            NumberFormatInfo   info = provider == null ? NumberFormatInfo.CurrentInfo : NumberFormatInfo.GetInstance(provider);
            ValueStringBuilder sb;

            unsafe
            {
                char *stackPtr = stackalloc char[CharStackBufferSize];
                sb = new ValueStringBuilder(new Span <char>(stackPtr, CharStackBufferSize));
            }

            int  digits;
            char fmt = ParseFormatSpecifier(format, out digits);

            int          precision = FLOAT_PRECISION;
            NumberBuffer number    = new NumberBuffer();

            switch (fmt)
            {
            case 'R':
            case 'r':
            {
                // In order to give numbers that are both friendly to display and round-trippable, we parse
                // the number using 7 digits and then determine if it round trips to the same value. If it
                // does, we convert that NUMBER to a string, otherwise we reparse using 9 digits and display
                // that.
                DoubleToNumber(value, FLOAT_PRECISION, ref number);
                if (number.scale == SCALE_NAN)
                {
                    return(info.NaNSymbol);
                }
                if (number.scale == SCALE_INF)
                {
                    return(number.sign ? info.NegativeInfinitySymbol : info.PositiveInfinitySymbol);
                }

                if ((float)NumberToDouble(ref number) == value)
                {
                    NumberToString(ref sb, ref number, 'G', FLOAT_PRECISION, info, false);
                }
                else
                {
                    DoubleToNumber(value, 9, ref number);
                    NumberToString(ref sb, ref number, 'G', 9, info, false);
                }
                return(sb.GetString());
            }

            case 'E':
            case 'e':
                // Here we round values less than E14 to 15 digits
                if (digits > 6)
                {
                    precision = 9;
                }
                break;

            case 'G':
            case 'g':
                // Here we round values less than G15 to 15 digits, G16 and G17 will not be touched
                if (digits > 7)
                {
                    precision = 9;
                }
                break;
            }

            DoubleToNumber(value, precision, ref number);
            if (number.scale == SCALE_NAN)
            {
                return(info.NaNSymbol);
            }
            if (number.scale == SCALE_INF)
            {
                return(number.sign ? info.NegativeInfinitySymbol : info.PositiveInfinitySymbol);
            }

            if (fmt != 0)
            {
                NumberToString(ref sb, ref number, fmt, digits, info, false);
            }
            else
            {
                NumberToStringFormat(ref sb, ref number, format, info);
            }
            return(sb.GetString());
        }