Beispiel #1
0
        public static unsafe float CopySign(float x, float y)
        {
            // This method is required to work for all inputs,
            // including NaN, so we operate on the raw bits.

            var xbits = BitConverter.SingleToInt32Bits(x);
            var ybits = BitConverter.SingleToInt32Bits(y);

            // If the sign bits of x and y are not the same,
            // flip the sign bit of x and return the new value;
            // otherwise, just return x

            if ((xbits ^ ybits) < 0)
            {
                return(BitConverter.Int32BitsToSingle(xbits ^ int.MinValue));
            }

            return(x);
        }
Beispiel #2
0
        public static float BitDecrement(float x)
        {
            var bits = BitConverter.SingleToInt32Bits(x);

            if ((bits & 0x7F800000) >= 0x7F800000)
            {
                // NaN returns NaN
                // -Infinity returns -Infinity
                // +Infinity returns float.MaxValue
                return((bits == 0x7F800000) ? float.MaxValue : x);
            }

            if (bits == 0x00000000)
            {
                // +0.0 returns -float.Epsilon
                return(-float.Epsilon);
            }

            // Negative values need to be incremented
            // Positive values need to be decremented

            bits += ((bits < 0) ? +1 : -1);
            return(BitConverter.Int32BitsToSingle(bits));
        }
Beispiel #3
0
        public static float BitIncrement(float x)
        {
            var bits = BitConverter.SingleToInt32Bits(x);

            if ((bits & 0x7F800000) >= 0x7F800000)
            {
                // NaN returns NaN
                // -Infinity returns float.MinValue
                // +Infinity returns +Infinity
                return((bits == unchecked ((int)(0xFF800000))) ? float.MinValue : x);
            }

            if (bits == unchecked ((int)(0x80000000)))
            {
                // -0.0 returns float.Epsilon
                return(float.Epsilon);
            }

            // Negative values need to be decremented
            // Positive values need to be incremented

            bits += ((bits < 0) ? -1 : +1);
            return(BitConverter.Int32BitsToSingle(bits));
        }
Beispiel #4
0
        public object?ToObject()
        {
            switch (CVType)
            {
            case CV_EMPTY:
                return(null);

            case CV_BOOLEAN:
                return((object)((int)_data != 0));

            case CV_I1:
                return((object)((sbyte)_data));

            case CV_U1:
                return((object)((byte)_data));

            case CV_CHAR:
                return((object)((char)_data));

            case CV_I2:
                return((object)((short)_data));

            case CV_U2:
                return((object)((ushort)_data));

            case CV_I4:
                return((object)((int)_data));

            case CV_U4:
                return((object)((uint)_data));

            case CV_I8:
                return((object)((long)_data));

            case CV_U8:
                return((object)((ulong)_data));

            case CV_R4:
                return((object)(BitConverter.Int32BitsToSingle((int)_data)));

            case CV_R8:
                return((object)(BitConverter.Int64BitsToDouble(_data)));

            case CV_DATETIME:
                return(new DateTime(_data));

            case CV_TIMESPAN:
                return(new TimeSpan(_data));

            case CV_ENUM:
                return(BoxEnum());

            case CV_MISSING:
                return(Type.Missing);

            case CV_NULL:
                return(System.DBNull.Value);

            case CV_DECIMAL:
            case CV_STRING:
            case CV_OBJECT:
            default:
                return(_objref);
            }
        }
Beispiel #5
0
        public static float Round(float x)
        {
            // ************************************************************************************
            // IMPORTANT: Do not change this implementation without also updating MathF.Round(float),
            //            FloatingPointUtils::round(double), and FloatingPointUtils::round(float)
            // ************************************************************************************

            // This is based on the 'Berkeley SoftFloat Release 3e' algorithm

            uint bits     = (uint)BitConverter.SingleToInt32Bits(x);
            int  exponent = float.ExtractExponentFromBits(bits);

            if (exponent <= 0x7E)
            {
                if ((bits << 1) == 0)
                {
                    // Exactly +/- zero should return the original value
                    return(x);
                }

                // Any value less than or equal to 0.5 will always round to exactly zero
                // and any value greater than 0.5 will always round to exactly one. However,
                // we need to preserve the original sign for IEEE compliance.

                float result = ((exponent == 0x7E) && (float.ExtractSignificandFromBits(bits) != 0)) ? 1.0f : 0.0f;
                return(CopySign(result, x));
            }

            if (exponent >= 0x96)
            {
                // Any value greater than or equal to 2^23 cannot have a fractional part,
                // So it will always round to exactly itself.

                return(x);
            }

            // The absolute value should be greater than or equal to 1.0 and less than 2^23
            Debug.Assert((0x7F <= exponent) && (exponent <= 0x95));

            // Determine the last bit that represents the integral portion of the value
            // and the bits representing the fractional portion

            uint lastBitMask   = 1U << (0x96 - exponent);
            uint roundBitsMask = lastBitMask - 1;

            // Increment the first fractional bit, which represents the midpoint between
            // two integral values in the current window.

            bits += lastBitMask >> 1;

            if ((bits & roundBitsMask) == 0)
            {
                // If that overflowed and the rest of the fractional bits are zero
                // then we were exactly x.5 and we want to round to the even result

                bits &= ~lastBitMask;
            }
            else
            {
                // Otherwise, we just want to strip the fractional bits off, truncating
                // to the current integer value.

                bits &= ~roundBitsMask;
            }

            return(BitConverter.Int32BitsToSingle((int)bits));
        }