Example #1
0
        static int f2s_buffered_n(float f, Span <char> result)
        {
            // Step 1: Decode the floating-point number, and unify normalized and subnormal cases.
            uint bits = float_to_bits(f);

            // Decode bits into sign, mantissa, and exponent.
            bool ieeeSign     = ((bits >> (FLOAT_MANTISSA_BITS + FLOAT_EXPONENT_BITS)) & 1) != 0;
            uint ieeeMantissa = bits & ((1u << FLOAT_MANTISSA_BITS) - 1);
            uint ieeeExponent = (bits >> FLOAT_MANTISSA_BITS) & ((1u << FLOAT_EXPONENT_BITS) - 1);

            // Case distinction; exit early for the easy cases.
            if (ieeeExponent == ((1u << FLOAT_EXPONENT_BITS) - 1u) || (ieeeExponent == 0 && ieeeMantissa == 0))
            {
                return(copy_special_str(result, ieeeSign, Convert.ToBoolean(ieeeExponent), Convert.ToBoolean(ieeeMantissa)));
            }

            floating_decimal_32 v = f2d(ieeeMantissa, ieeeExponent);

            return(to_chars(v, ieeeSign, result));
        }
Example #2
0
        static int to_chars(floating_decimal_32 v, bool sign, Span <char> result)
        {
            // Step 5: Print the decimal representation.
            int index = 0;

            if (sign)
            {
                result[index++] = '-';
            }

            uint output  = v.mantissa;
            int  olength = decimalLength9(output);

            // Print the decimal digits.
            // The following code is equivalent to:
            // for (uint i = 0; i < olength - 1; ++i) {
            //    uint c = output % 10; output /= 10;
            //   result[index + olength - i] = (char) ('0' + c);
            // }
            // result[index] = '0' + output % 10;
            int i = 0;

            while (output >= 10000)
            {
                uint c = output % 10000;
                output /= 10000;
                uint c0 = (c % 100) << 1;
                uint c1 = (c / 100) << 1;
                memcpy(result.Slice(index + olength - i - 1), DIGIT_TABLE, c0, 2);
                memcpy(result.Slice(index + olength - i - 3), DIGIT_TABLE, c1, 2);
                i += 4;
            }
            if (output >= 100)
            {
                uint c = (output % 100) << 1;
                output /= 100;
                memcpy(result.Slice(index + olength - i - 1), DIGIT_TABLE, c, 2);
                i += 2;
            }
            if (output >= 10)
            {
                uint c = output << 1;
                // We can't use memcpy here: the decimal dot goes between these two digits.
                result[index + olength - i] = DIGIT_TABLE[c + 1];
                result[index] = DIGIT_TABLE[c];
            }
            else
            {
                result[index] = (char)('0' + output);
            }

            // Print decimal point if needed.
            if (olength > 1)
            {
                result[index + 1] = '.';
                index            += olength + 1;
            }
            else
            {
                ++index;
            }

            // Print the exponent.
            result[index++] = 'E';
            int exp = v.exponent + (int)olength - 1;

            if (exp < 0)
            {
                result[index++] = '-';
                exp             = -exp;
            }

            if (exp >= 10)
            {
                memcpy(result.Slice(index), DIGIT_TABLE, 2 * exp, 2);
                index += 2;
            }
            else
            {
                result[index++] = (char)('0' + exp);
            }

            return(index);
        }