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); }
// 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; }
/// <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)); }
public BitMask MinRealU => _environment.MinRealU; // "minrealu" #endregion #region Unum constructors public Unum(UnumEnvironment environment) { _environment = environment; UnumBits = new BitMask(_environment.Size); }