public Binary64 NextRepresentableValue(Binary64InsignificantBits insignificantBits) { ulong lsb = (ulong)1 << insignificantBits; ulong mask = lsb - 1; ulong maxMask = BITS_MAX_POSITIVE ^ mask; // Only keep the significant bits, drop the sign. ulong nextBits = _bits & maxMask; if (Sign.IsNegative) { if (nextBits != 0) { // Some negative number getting smaller. nextBits -= lsb; nextBits |= BITS_SIGN; } } else { if (nextBits == maxMask) { throw new InvalidOperationException(); } // Some positive number getting larger. nextBits += lsb; } return(new Binary64(nextBits)); }
public Binary64 Round(Binary64InsignificantBits insignificantBits) { // Don't round special values... if (IsNan || IsInfinite) { return(new Binary64(_bits)); } ulong lsb = (ulong)1 << insignificantBits; ulong mask = lsb - 1; ulong maxMask = BITS_MAX_POSITIVE ^ mask; // Only keep the significant bits, drop the sign. ulong bits = _bits & maxMask; // Imlpement rounding by adding half of the maximum value that can // be represented by the insignificant bits, and then truncating. bits += mask / 2; // It is possible that the significand just overflowed. If so, we // just rounded up to one of the special values (Infinity or Nan). // Simply return +/- infinite. if (bits > BITS_MAX_NORMAL) { if (Sign.IsNegative) { // NegativeInfinity bits = BITS_SIGN | BITS_EXPONENT; } else { // PositiveInfinity bits = BITS_EXPONENT; } } else { // Restore the sign. We never round from negative to positive. if (Sign.IsNegative) { bits |= BITS_SIGN; } } return(new Binary64(bits)); }
public Binary64 PreviousRepresentableValue(Binary64InsignificantBits insignificantBits) { ulong lsb = (ulong)1 << (int)insignificantBits; ulong mask = lsb - 1; ulong maxMask = BITS_MAX_POSITIVE ^ mask; // Only keep the significant bits, drop the sign. ulong prevBits = _bits & maxMask; if (Sign.IsPositive) { if (prevBits != 0) { // Some positive number getting smaller prevBits -= lsb; } else { // Positive 0 will turn into negative 0. prevBits |= BITS_SIGN; } } else { if (prevBits == maxMask) { throw new InvalidOperationException(); } // Some negative number getting larger. prevBits -= lsb; prevBits |= BITS_SIGN; } return(new Binary64(prevBits)); }
public static double RoundInsignificantBits(this double value, Binary64InsignificantBits insignificantBits) { return(((Binary64)value).Round(insignificantBits)); }
public static double GetPreviousRepresentableValue(this double value, Binary64InsignificantBits insignificantBits) { return(((Binary64)value).PreviousRepresentableValue(insignificantBits)); }
public Binary64 Round(Binary64InsignificantBits insignificantBits) { // Don't round special values... if (IsNan || IsInfinite) { return new Binary64(this._bits); } ulong lsb = (ulong)1 << (int)insignificantBits; ulong mask = lsb - 1; ulong maxMask = BITS_MAX_POSITIVE ^ mask; // Only keep the significant bits, drop the sign. ulong bits = _bits & maxMask; // Imlpement rounding by adding half of the maximum value that can // be represented by the insignificant bits, and then truncating. bits += (mask / 2); // It is possible that the significand just overflowed. If so, we // just rounded up to one of the special values (Infinity or Nan). // Simply return +/- infinite. if (bits > BITS_MAX_NORMAL) { if (Sign.IsNegative) { // NegativeInfinity bits = BITS_SIGN | BITS_EXPONENT; } else { // PositiveInfinity bits = BITS_EXPONENT; } } else { // Restore the sign. We never round from negative to positive. if (Sign.IsNegative) { bits |= BITS_SIGN; } } return new Binary64(bits); }
public Binary64 PreviousRepresentableValue(Binary64InsignificantBits insignificantBits) { ulong lsb = (ulong)1 << (int)insignificantBits; ulong mask = lsb - 1; ulong maxMask = BITS_MAX_POSITIVE ^ mask; // Only keep the significant bits, drop the sign. ulong prevBits = _bits & maxMask; if (Sign.IsPositive) { if (prevBits != 0) { // Some positive number getting smaller prevBits -= lsb; } else { // Positive 0 will turn into negative 0. prevBits |= BITS_SIGN; } } else { if (prevBits == maxMask) { throw new InvalidOperationException(); } // Some negative number getting larger. prevBits -= lsb; prevBits |= BITS_SIGN; } return new Binary64(prevBits); }
public static double RoundInsignificantBits(this double value, Binary64InsignificantBits insignificantBits) { return ((Binary64)value).Round(insignificantBits); }
public static double GetPreviousRepresentableValue(this double value, Binary64InsignificantBits insignificantBits) { return ((Binary64)value).PreviousRepresentableValue(insignificantBits); }