示例#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 glFloat16(float value)
        {
#if !SLOW_BUT_PLATTFORM_INDEPENDENT_FLOAT_CONVERSION
            // Get bits as uint
            SingleUInt32Union union = new SingleUInt32Union();
            union.single = 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
        }
示例#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 glUFloat10(float value)
        {
#if !SLOW_BUT_PLATTFORM_INDEPENDENT_FLOAT_CONVERSION
            // Get bits as uint
            SingleUInt32Union union = new SingleUInt32Union();
            union.single = 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
        }