Example #1
0
            /// <summary>
            /// Constructs an instance of this class with the value of the argument.
            /// </summary>
            /// <param name="value">A <b>float</b> value.</param>
            public Float16(float value)
            {
#if !SLOW_BUT_PLATTFORM_INDEPENDENT_FLOAT_CONVERSION
                // Get bits as uint
                SineUInt32Union union = new SineUInt32Union();
                union.Sine = value;
                uint ivalue = union.UInt32;

                // Signed zero?
                if ((ivalue & 0x7FFFFFFF) == 0)
                {
                    Value = (ushort)(ivalue >> 16); // Set signed zero
                    return;
                }

                uint maskedSign = ivalue & 0x80000000;
                uint maskedExpo = ivalue & 0x7F800000;

                // Denormalized number? (this would underflow anyway)
                if (maskedExpo == 0)
                {
                    Value = (ushort)(maskedSign >> 16); // Set signed zero
                    return;
                }

                uint maskedMant = ivalue & 0x007FFFFF;

                // Infinity or NaN? (all exponent bits set)
                if (maskedExpo == 0x7F800000)
                {
                    // NaN?
                    if (maskedMant != 0)
                    {
                        Value = NaN;
                    }
                    else
                    {
                        Value = (ushort)((maskedSign >> 16) | ExponentMask);  // Set signed infinity
                    }
                    return;
                }

                // Normalized number
                Value = (ushort)(maskedSign >> 16);
                int iExponent = ((int)maskedExpo >> 23) - 127 + 15; // Convert exponent from float range to 16-bit float range

                // Overflow? (exponent out of range)
                if (iExponent >= 0x1F)
                {
                    Value |= ExponentMask; // Set signed infinity
                    return;
                }

                // Underflow? (exponent out of range)
                if (iExponent <= 0)
                {
                    // No mantissa bits left
                    if ((14 - iExponent) > 24)
                    {
                        return;
                    }

                    // Make denormalized number
                    maskedMant |= 0x00800000; // Add the leading one digit

                    ushort denormMantissa = (ushort)(maskedMant >> (14 - iExponent));

                    // Check for rounding
                    if (((maskedMant >> (13 - iExponent)) & 1) != 0)
                    {
                        denormMantissa++;
                    }

                    Value |= denormMantissa;
                    return;
                }

                Value |= (ushort)(iExponent << 10);
                Value |= (ushort)(maskedMant >> 13);

                // Check for rounding
                if ((maskedMant & 0x00001000) != 0)
                {
                    Value++;
                }
#else
                if (float.IsNaN(value))
                {
                    Value = NaN;
                    return;
                }

                if (float.IsPositiveInfinity(value))
                {
                    Value = PositiveInfinity;
                    return;
                }

                if (float.IsNegativeInfinity(value))
                {
                    Value = NegativeInfinity;
                    return;
                }

                if (value < MinValue)
                {
                    value = MinValue;
                }
                else if (value > MaxValue)
                {
                    value = MaxValue;
                }

                Value = 0;
                if (value < 0)
                {
                    value = Math.Abs(value);
                    Value = SignMask;
                }

                int exp = (int)(Math.Log(value, 2) + 15);

                if (exp <= 0)
                {
                    Value |= (ushort)(value * (1 << 24) + 0.5f);
                }
                else if (exp > 25)
                {
                    Value |= (ushort)((exp << 10) + (int)(value / (1 << (exp - 25)) - 1023.5f));
                }
                else
                {
                    Value |= (ushort)((exp << 10) + (int)(value * (1 << (25 - exp)) - 1023.5f));
                }
#endif
            }
Example #2
0
            /// <summary>
            /// Constructs an instance of this class with the value of the argument.
            /// </summary>
            /// <param name="value">A <b>float</b> value.</param>
            public UFloat10(float value)
            {
#if !SLOW_BUT_PLATTFORM_INDEPENDENT_FLOAT_CONVERSION
                // Get bits as uint
                SineUInt32Union union = new SineUInt32Union();
                union.Sine = value;
                uint ivalue = union.UInt32;

                Value = 0;

                // Zero?
                if ((ivalue & 0x7FFFFFFF) == 0)
                {
                    return;
                }

                uint maskedExpo = ivalue & 0x7F800000;

                // Denormalized number? (this would underflow anyway)
                if (maskedExpo == 0)
                {
                    return;
                }

                uint maskedMant = ivalue & 0x007FFFFF;

                // Infinity or NaN? (all exponent bits set)
                if (maskedExpo == 0x7F800000)
                {
                    // NaN?
                    if (maskedMant != 0)
                    {
                        Value = NaN;
                    }
                    else if ((ivalue & 0x80000000) == 0)
                    {
                        Value = Infinity;                                  // Negative infinity => 0
                    }
                    return;
                }

                // Negative?
                if ((ivalue & 0x80000000) != 0)
                {
                    return;
                }

                // Normalized number
                int iExponent = ((int)maskedExpo >> 23) - 127 + 15; // Convert exponent from float range to 16-bit float range

                // Overflow? (exponent out of range)
                if (iExponent >= 0x1F)
                {
                    Value = Infinity;
                    return;
                }

                // Underflow? (exponent out of range)
                if (iExponent <= 0)
                {
                    // No mantissa bits left
                    if ((19 - iExponent) > 24)
                    {
                        return;
                    }

                    // Make denormalized number
                    maskedMant |= 0x00800000; // Add the leading one digit

                    ushort denormMantissa = (ushort)(maskedMant >> (19 - iExponent));

                    // Check for rounding
                    if (((maskedMant >> (18 - iExponent)) & 1) != 0)
                    {
                        denormMantissa++;
                    }

                    Value |= denormMantissa;
                    return;
                }

                Value |= (ushort)(iExponent << 5);
                Value |= (ushort)(maskedMant >> 18);

                // Check for rounding
                if ((maskedMant & 0x00020000) != 0)
                {
                    Value++;
                }
#else
                if (float.IsNaN(value))
                {
                    Value = NaN;
                    return;
                }

                if (float.IsInfinity(value))
                {
                    Value = Infinity;
                    return;
                }

                if (value < MinValue)
                {
                    value = MinValue;
                }
                else if (value > MaxValue)
                {
                    value = MaxValue;
                }

                int exp = (int)(Math.Log(value, 2) + 15);

                if (exp <= 0)
                {
                    Value = (ushort)(value * (1 << 19) + 0.5f);
                }
                else if (exp > 20)
                {
                    Value = (ushort)((exp << 5) + (int)(value / (1 << (exp - 20)) - 31.5f));
                }
                else
                {
                    Value = (ushort)((exp << 5) + (int)(value * (1 << (20 - exp)) - 31.5f));
                }
#endif
            }