Exemplo n.º 1
0
 public void TestIntegerReinterpretation()
 {
     Assert.AreEqual(
         12345.0f,
         FloatHelper.ReinterpretAsFloat(FloatHelper.ReinterpretAsInt(12345.0f)),
         "Number hasn't changed after mirrored reinterpretation"
         );
 }
Exemplo n.º 2
0
        /// <summary>
        ///   Appends a floating point value to a string builder without generating garbage
        /// </summary>
        /// <param name="builder">String builder the value will be appended to</param>
        /// <param name="value">Value that will be appended to the string builder</param>
        /// <param name="decimalPlaces">Maximum number of decimal places to display</param>
        /// <returns>Whether the value was inside the algorithm's supported range</returns>
        /// <remarks>
        ///   Uses an algorithm that covers the sane range of possible values but will
        ///   fail to render extreme values, NaNs and infinity. In these cases, false
        ///   is returned and the traditional double.ToString() method can be used.
        /// </remarks>
        public static bool Append(StringBuilder builder, float value, int decimalPlaces)
        {
            const int ExponentBits       = 0xFF; // Bit mask for the exponent bits
            const int FractionalBitCount = 23;   // Number of bits for fractional part
            const int ExponentBias       = 127;  // Bias subtraced from exponent
            const int NumericBitCount    = 31;   // Bits without sign

            // You don't need modify these as they're calculated based on
            // the constants assigned above.
            const int FractionalBits            = (2 << FractionalBitCount) - 1;
            const int HighestFractionalBit      = (1 << FractionalBitCount);
            const int FractionalBitCountPlusOne = FractionalBitCount + 1;

            int intValue = FloatHelper.ReinterpretAsInt(value);
            int exponent = ((intValue >> FractionalBitCount) & ExponentBits) - ExponentBias;
            int mantissa = (intValue & FractionalBits) | HighestFractionalBit;

            int integral;
            int fractional;

            if (exponent >= 0)
            {
                if (exponent >= FractionalBitCount)
                {
                    if (exponent >= NumericBitCount)
                    {
                        return(false);
                    }
                    integral   = mantissa << (exponent - FractionalBitCount);
                    fractional = 0;
                }
                else
                {
                    integral   = mantissa >> (FractionalBitCount - exponent);
                    fractional = (mantissa << (exponent + 1)) & FractionalBits;
                }
            }
            else
            {
                if (exponent < -FractionalBitCount)
                {
                    return(false);
                }
                integral   = 0;
                fractional = (mantissa & FractionalBits) >> -(exponent + 1);
            }

            // Build the integral part
            if (intValue < 0)
            {
                builder.Append('-');
            }
            if (integral == 0)
            {
                builder.Append('0');
            }
            else
            {
                recursiveAppend(builder, integral);
            }

            if (decimalPlaces > 0)
            {
                builder.Append('.');

                // Build the fractional part
                if (fractional == 0)
                {
                    builder.Append('0');
                }
                else
                {
                    while (fractional != 0)
                    {
                        fractional *= 10;
                        int digit = (fractional >> FractionalBitCountPlusOne);
                        builder.Append(numbers[digit]);
                        fractional &= FractionalBits;

                        --decimalPlaces;
                        if (decimalPlaces == 0)
                        {
                            break;
                        }
                    }
                }
            }

            return(true);
        }