Exemplo n.º 1
0
        public Unum(UnumEnvironment environment, BitMask bits)
        {
            _environment = environment;

            // To be sure that UnumBits has the same size as the environment. Excess bits will be truncated.
            UnumBits = BitMask.FromImmutableArray(bits.Segments, _environment.Size);
        }
Exemplo n.º 2
0
        // This doesn't work for all cases yet.
        //public Unum(UnumEnvironment environment, float number)
        //{
        //    _environment = environment;

        //    // Handling special cases first.
        //    if (float.IsNaN(number))
        //    {
        //        UnumBits = _environment.QuietNotANumber;
        //        return;
        //    }
        //    if (float.IsPositiveInfinity(number))
        //    {
        //        UnumBits = _environment.PositiveInfinity;
        //        return;
        //    }
        //    if (float.IsNegativeInfinity(number))
        //    {
        //        UnumBits = _environment.NegativeInfinity;
        //        return;
        //    }


        //    UnumBits = new BitMask(_environment.Size);
        //    var floatExponentBits = (BitConverter.ToUInt32(BitConverter.GetBytes(number), 0) << 1) >> 24;

        //    // These are the only uncertain cases that we can safely handle without Ubounds.
        //    if (ExponentSizeMax < ExponentValueToExponentSize((int)floatExponentBits - 127))
        //    {
        //        // The exponent is too big, so we express the number as the largest possible signed value,
        //        // but the Unum is uncertain, meaning that it's finite, but too big to express.
        //        if (floatExponentBits - 127 > 0)
        //            UnumBits = IsPositive() ? LargestPositive : LargestNegative;
        //        else // If the exponent is too small, we will handle it as a signed uncertain zero.
        //        {
        //            UnumBits = new BitMask(Size);
        //            if (!IsPositive()) Negate();
        //        }

        //        SetUncertainityBit(true);

        //        return;
        //    }


        //    var floatFractionBits = (BitConverter.ToUInt32(BitConverter.GetBytes(number), 0) << 9) >> 9;
        //    uint resultFractionSize = 23;
        //    uint floatFractionBitsSize = 23;

        //    if (floatFractionBits == 0) resultFractionSize = 0;
        //    else
        //        while (floatFractionBits % 2 == 0)
        //        {
        //            resultFractionSize -= 1;
        //            floatFractionBits >>= 1;
        //            floatFractionBitsSize = resultFractionSize;
        //        }


        //    var uncertainty = false;

        //    if (FractionSizeMax + 1 < resultFractionSize)
        //    {
        //        resultFractionSize = ((uint)FractionSizeMax - 1);
        //        uncertainty = true;
        //    }
        //    else if (resultFractionSize > 0) resultFractionSize = (resultFractionSize - 1);

        //    var resultFraction = uncertainty ?
        //        new BitMask(new uint[] { floatFractionBits >> (int)floatFractionBitsSize - FractionSizeMax }, Size) :
        //        new BitMask(new uint[] { floatFractionBits }, Size);
        //    var resultExponent = ExponentValueToExponentBits((int)(floatExponentBits - 127), Size);
        //    var floatBits = BitConverter.ToUInt32(BitConverter.GetBytes(number), 0);
        //    var resultSignBit = (floatBits > uint.MaxValue / 2);
        //    var resultExponentSize = (ExponentValueToExponentSize((int)floatExponentBits - 127) - 1);


        //    AssembleUnumBits(resultSignBit, resultExponent, resultFraction,
        //        uncertainty, resultExponentSize, resultFractionSize);
        //}

        /// <summary>
        /// Creates a Unum of the given environment initialized with the value of the uint.
        /// </summary>
        /// <param name="environment">The Unum environment.</param>
        /// <param name="value">The uint value to initialize the new Unum with.</param>
        public Unum(UnumEnvironment environment, uint value)
        {
            _environment = environment;
            // Creating an array of the size needed to call the other constructor.
            // This is necessary because in Hastlayer only arrays with dimensions defined at compile-time are supported.
            var valueArray = new uint[environment.EmptyBitMask.SegmentCount];

            valueArray[0] = value;

            UnumBits = new Unum(environment, valueArray).UnumBits;
        }
Exemplo n.º 3
0
        /// <summary>
        /// Creates a Unum initialized with a value that is defined by the bits in a uint array.
        /// </summary>
        /// <param name="environment">The Unum environment.</param>
        /// <param name="value">
        /// The uint array which defines the Unum's value as an integer.
        /// To use with Hastlayer this should be the same size as the BitMasks in the given environment.
        /// </param>
        /// <param name="negative">Defines whether the number is positive or not.</param>
        public Unum(UnumEnvironment environment, uint[] value, bool negative = false)
        {
            _environment = environment;

            UnumBits = new BitMask(value, environment.Size);
            if (UnumBits == _environment.EmptyBitMask)
            {
                return;
            }

            // Handling the case when the number wouldn't fit in the range of the environment.
            if (UnumHelper.LargestExpressablePositiveInteger(environment) != environment.EmptyBitMask)
            {
                if (UnumBits > UnumHelper.LargestExpressablePositiveInteger(environment))
                {
                    UnumBits = negative ? environment.LargestNegative | environment.UncertaintyBitMask
                        : environment.LargestPositive | environment.UncertaintyBitMask;
                    return;
                }
            }
            var uncertainityBit = false;

            // Putting the actual value in a BitMask.
            var exponent = new BitMask(value, Size);

            // The value of the exponent is one less than the number of binary digits in the integer.
            var exponentValue = new BitMask((uint)(exponent.GetMostSignificantOnePosition() - 1), Size);

            // Calculating the number of bits needed to represent the value of the exponent.
            var exponentSize = exponentValue.GetMostSignificantOnePosition();

            // If the value of the exponent is not a power of 2,
            // then one more bit is needed to represent the biased value.
            if ((exponentValue.GetLowest32Bits() & exponentValue.GetLowest32Bits() - 1) > 0)
            {
                exponentSize++;
            }

            // Handling input numbers that don't fit in the range of the given environment.
            if (exponentSize > ExponentSizeMax)
            {
                UnumBits = negative ? (environment.LargestNegative | environment.UncertaintyBitMask) - 1
                    : (environment.LargestPositive | environment.UncertaintyBitMask) - 1;
                return;
            }
            // Calculating the bias from the number of bits representing the exponent.
            var bias = exponentSize == 0 ? 0 : (1 << exponentSize - 1) - 1;

            // Applying the bias to the exponent.
            exponent = exponentValue + (uint)bias;

            // Putting the actual value in a BitMask.
            var fraction = new BitMask(value, Size);

            // Shifting out the zeros after the least significant 1-bit.
            fraction = fraction.ShiftOutLeastSignificantZeros();

            // Calculating the number of bits needed to represent the fraction.
            var fractionSize = fraction.GetMostSignificantOnePosition();


            /* If there's a hidden bit and it's 1,
             * then the most significant 1-bit of the fraction is stored there,
             * so we're removing it from the fraction and decreasing fraction size accordingly. */
            if (exponent.GetLowest32Bits() > 0)
            {
                fractionSize--;
                fraction = fraction.SetZero(fractionSize);
            }
            // Handling input numbers that fit in the range, but are too big to represent exactly.
            if (fractionSize > FractionSizeMax)
            {
                fraction        = fraction >> FractionSizeMax - fractionSize;
                uncertainityBit = true;
            }

            UnumBits = AssembleUnumBits(negative, exponent, fraction,
                                        uncertainityBit, (byte)(exponentSize > 0 ? --exponentSize : 0), (ushort)(fractionSize > 0 ? --fractionSize : 0));
        }
Exemplo n.º 4
0
        public BitMask                   MinRealU => _environment.MinRealU; // "minrealu"

        #endregion

        #region Unum constructors

        public Unum(UnumEnvironment environment)
        {
            _environment = environment;

            UnumBits = new BitMask(_environment.Size);
        }