/// <summary> /// Returns the smaller of <see cref="Posit8"/> numbers. /// </summary> /// <param name="x">The first of two <see cref="Posit8"/> numbers to compare.</param> /// <param name="y">The second of two <see cref="Posit8"/> numbers to compare.</param> /// <returns> /// Parameter <paramref name="x"/> or <paramref name="y"/>, /// whichever is smaller. If <paramref name="x"/>, <paramref name="y"/>, /// or both <paramref name="x"/> and <paramref name="y"/> /// are equal to <c>NaR</c>, that value is returned. /// </returns> public static Posit8 Min(Posit8 x, Posit8 y) { if (Posit.IsNaR(x) || Posit.IsNaR(y)) { return(Posit8.NaR); } return(x <= y ? x : y); }
[TestCase(0b00000001, 0b01000001, 0b11000000, "minpos - 1.03125 = -1")] // bitNPlusOne public void TestSub(byte a, byte b, byte c, string op) { var pA = new Posit8(a); var pB = new Posit8(b); var pC = new Posit8(c); Console.WriteLine(op); Assert.That((pA - pB).ui, Is.EqualTo(pC.ui)); }
/// <summary> /// Returns the absolute value of a <see cref="Posit8"/> number. /// </summary> /// <param name="x">A number that is greater than or equal to MinValue, but less than or equal to MaxValue.</param> /// <returns>A <see cref="Posit8"/> number, x, such that 0 ≤ x ≤ MaxValue.</returns> public static Posit8 Abs(Posit8 x) { unchecked { const int CHAR_BIT = 8; // http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs var mask = (sbyte)x.ui >> sizeof(byte) * CHAR_BIT - 1; var result = (x.ui ^ mask) - mask; return(new Posit8((byte)result)); } }
/// <summary> /// Returns an integer that indicates the sign of a <see cref="Posit8"/> number. /// </summary> /// <param name="x">A signed number.</param> /// <returns>A number that indicates the sign of <paramref name="x"/></returns> public static int Sign(Posit8 x) { if ((x.ui & ~Posit8.SignMask) == 0) { return(0); // Zero or NaR } if ((x.ui & Posit8.SignMask) != 0) { return(-1); // Negative } return(1); }
public static posit8_t p8_roundToInt(posit8_t a) { var(sign, uiA) = a; if (uiA <= 0x20) { // 0 <= |pA| <= 1/2 rounds to zero. return(Posit8.Zero); } else if (uiA < 0x50) { // 1/2 < x < 3/2 rounds to 1. uiA = 0x40; } else if (uiA <= 0x64) { // 3/2 <= x <= 5/2 rounds to 2. uiA = 0x60; } else if (uiA >= 0x78) { // If |A| is 8 or greater, leave it unchanged. return(a); // This also takes care of the NaR case, 0x80. } else { var mask = (byte)0x20; var scale = 0; while ((mask & uiA) != 0) { scale += 1; mask >>= 1; } mask >>= scale; var bitLast = (uiA & mask) != 0; mask >>= 1; byte tmp = (byte)(uiA & mask); var bitNPlusOne = tmp != 0; uiA ^= tmp; tmp = (byte)(uiA & (mask - 1)); //bitsMore uiA ^= tmp; if (bitNPlusOne) { if (bitLast || (tmp != 0)) { uiA += (byte)(mask << 1); } } } return(new Posit8(sign, uiA)); }
public static posit8_t p8_ceil(posit8_t a) { var(sign, uiA) = a; if (uiA == 0) { return(a); } else if (uiA <= 0x40) { // 0 <= |pA| < 1 floor to zero.(if not negative and whole number) uiA = (byte)((sign && (uiA != 0x40)) ? 0x0 : 0x40); } else if (uiA <= 0x60) { // 1 <= x < 2 floor to 1 (if not negative and whole number) uiA = (byte)((sign & (uiA != 0x60)) ? 0x40 : 0x60); } else if (uiA <= 0x68) { // 2 <= x < 3 floor to 2 (if not negative and whole number) uiA = (byte)((sign & (uiA != 0x68)) ? 0x60 : 0x68); } else if (uiA >= 0x78) { // If |A| is 8 or greater, leave it unchanged. return(a); // This also takes care of the NaR case, 0x80. } else { byte mask = 0x20, scale = 0; while ((mask & uiA) != 0) { scale += 1; mask >>= 1; } mask >>= scale; mask >>= 1; var tmp = (byte)(uiA & mask); var bitNPlusOne = tmp != 0; uiA ^= tmp; tmp = (byte)(uiA & (mask - 1)); //bitsMore uiA ^= tmp; if (!sign && (bitNPlusOne || (tmp != 0))) { uiA += (byte)(mask << 1); } } return(new Posit8(sign, uiA)); }
/// <summary> /// Returns <c>e</c> raised to the specified power. /// </summary> /// <param name="x">A number specifying a power.</param> /// <returns>The number <c>e</c> raised to the power <paramref name="x"/>. If <paramref name="x"/> equals NaR, that value is returned.</returns> public static Posit8 Exp(Posit8 x) { return(p8_exp(x)); }
/// <summary> /// Returns a value with the magnitude of <paramref name="x"/> and the sign of <paramref name="y"/>. /// </summary> /// <param name="x">A number whose magnitude is used in the result.</param> /// <param name="y">A number whose sign is the used in the result.</param> /// <returns>A value with the magnitude of <paramref name="x"/> and the sign of <paramref name="y"/>.</returns> public static Posit8 CopySign(Posit8 x, Posit8 y) { return(((x.ui ^ y.ui) & Posit8.SignMask) == 0 ? x : -x); }
/// <summary> /// Returns the smallest integral value that is greater than /// or equal to the specified <see cref="Posit8"/> number. /// </summary> /// <param name="x">A <see cref="Posit8"/> number.</param> /// <returns> /// The smallest integral value that is greater than or equal to /// <paramref name="x"/>. If <paramref name="x"/> is equal to /// <c>NaR</c>, that value is returned. Note that this method /// returns a <see cref="Posit8"/> instead of an integral type. /// </returns> public static Posit8 Ceiling(Posit8 x) { return(p8_ceil(x)); }
public static posit8_t p8_exp(posit8_t pA) { return(new Posit8(p8Exp[pA.ui])); }
public static bool IsNaR(Posit8 p) => p.ui == Posit8.NaR.ui;
public static bool IsOne(Posit8 p) => p.ui == Posit8.One.ui;
public static bool IsZero(Posit8 p) => p.ui == Posit8.Zero.ui;
public DebugProxy(Posit8 value) : this(value.ui, Posit8.nbits, Posit8.es) { }
public static posit8_t p8_log(posit8_t a) { return(a.ui > 127 ? Posit8.NaR : new Posit8(p8Log[a.ui])); }
/// <summary> /// Returns the largest integral value less than or equal to the specified <see cref="Posit8"/> number. /// </summary> /// <param name="x">A <see cref="Posit8"/> number.</param> /// <returns>The largest integral value less than or equal to <paramref name="x"/>. If <paramref name="x"/> is equal to <c>NaR</c>, that value is returned.</returns> public static Posit8 Floor(Posit8 x) { return(p8_floor(x)); }
/// <summary> /// Returns the natural (base e) logarithm of a specified number. /// </summary> /// <param name="x">The number whose logarithm is to be found.</param> /// <returns>The natural logarithm of <paramref name="x"/>; that is, ln x, or log e x. </returns> /// <remarks>Parameter <paramref name="x"/> is specified as a base 10 number.</remarks> public static Posit8 Log(Posit8 x) { return(p8_log(x)); }
public static bool IsInfinity(Posit8 p) => p.ui == Posit8.Infinity.ui;
/// <summary> /// Rounds a <see cref="Posit8"/> number to the nearest integral value, /// and rounds midpoint values to the nearest even number. /// </summary> /// <param name="x">A <see cref="Posit8"/> number to be rounded.</param> /// <returns> /// The integer nearest <paramref name="x"/>. If the fractional component /// of <paramref name="x"/> is halfway between two integers, one of which /// is even and the other odd, then the even number is returned. Note that /// this method returns a <see cref="Posit8"/> instead of an integral type. /// </returns> public static Posit8 Round(Posit8 x) { return(p8_roundToInt(x)); }
public static bool IsNegative(Posit8 p) => (sbyte)p.ui < 0;
/// <summary> /// Returns the square root of a specified number. /// </summary> /// <param name="x">The number whose square root is to be found.</param> /// <returns>One of the values in the following table. /// <list type="table"> /// <listheader> /// <term><paramref name="x"/> parameter</term> /// <term>Return value</term> /// </listheader> /// <item> /// <term>Zero or positive</term> /// <term>The positive square root of <paramref name="x"/>.</term> /// </item> /// <item> /// <term>Negative</term> /// <term>NaR</term> /// </item> /// <item> /// <term>NaR</term> /// <term>NaR</term> /// </item> /// </list> /// </returns> public static Posit8 Sqrt(Posit8 x) { return(p8_sqrt(x)); }
public static bool IsZeroOrNaR(Posit8 p) { return((p.ui & (Posit8.SignMask - 1)) == 0); }