public static MiniFloat operator *(MiniFloat Multiplicand, MiniFloat Multiplier) { /* M * N = (M_mant * N_mant) * 2^(M_sign + N_sign) */ MiniFloat m = Multiplicand.Copy(); MiniFloat n = Multiplier.Copy(); /* Add leading ones */ m.Mantissa = '1' + m.Mantissa; n.Mantissa = '1' + n.Mantissa; /* Multipliy the mantissas */ Binary newMantissa = m.Mantissa * n.Mantissa; /* Add the non-biased exponents, create new biased exponent */ int e = (Convert.ToInt32(m.Exponent.BaseChange()) - INTBIAS) + (Convert.ToInt32(n.Exponent.BaseChange()) - INTBIAS); Binary newExponent = new Binary(Binary.BaseChange(e + INTBIAS, 10, 2)); char newSignbit = NewSignbit(m.Signbit, n.Signbit); MiniFloat result = new MiniFloat(newSignbit, newExponent, newMantissa); // Will have "11.[...]" or "10" at the start // OR, if both were 000 000 -> 1.000 * 1.000 = 1.000 //if (!(m.Mantissa.Body == "1000" && n.Mantissa.Body == "1000")) { result.Exponent += new Binary("0001"); //} /* Remove leading one */ result.Mantissa.Body = result.Mantissa.Body.Substring(1); return(result); }
public double ToDouble(MiniFloat a) { double sumE = 0; for (int i = a.Exponent.Count - 1; i >= 0; i--) { if (a.Exponent.Get(i)) { sumE += Math.Pow(2, a.Exponent.Count - i - 1); } } double sumM = 0; for (int i = 0; i < a.Mantissa.Count; i++) { if (a.Mantissa.Get(i)) { if (i == 0 && a.Sign) { sumM += -1 / Math.Pow(2, i); } else { sumM += 1 / Math.Pow(2, i); } } } double x = (sumM) * Math.Pow(2, exp); return(x); }
public static MiniFloat operator /(MiniFloat Dividend, MiniFloat Divisor) { MiniFloat m = Dividend.Copy(); MiniFloat n = Divisor.Copy(); m.Mantissa = '1' + m.Mantissa; n.Mantissa = '1' + n.Mantissa; Binary newMantissa = m.Mantissa / n.Mantissa; /* Sub exponents */ int e = (Convert.ToInt32(m.Exponent.BaseChange()) - INTBIAS) - (Convert.ToInt32(n.Exponent.BaseChange()) - INTBIAS); Binary newExponent = new Binary(Binary.BaseChange(e + INTBIAS, 10, 2)); char newSignbit = NewSignbit(m.Signbit, n.Signbit); MiniFloat result = new MiniFloat(newSignbit, newExponent, newMantissa); /* Remove leading */ result.Mantissa.Body = result.Mantissa.Body.Substring(1); while (result.Mantissa.Length < 3) { result.Mantissa += '0'; } return(result); }
/* Operators */ public static MiniFloat operator +(MiniFloat Augend, MiniFloat Addend) { MiniFloat m = Augend.Copy(); MiniFloat n = Addend.Copy(); m.Mantissa = '1' + m.Mantissa; n.Mantissa = '1' + n.Mantissa; Normalize(ref m, ref n); if (m.Signbit == '0' && n.Signbit == '0') { return(add(m, n)); } else if ((m.Signbit == '1' && n.Signbit == '0') || (n.Signbit == '1' && m.Signbit == '0')) { if (m.Mantissa > n.Mantissa) { return(sub(m, n)); } else if (n.Mantissa > m.Mantissa) { return(sub(n, m)); } else /* Equal */ return { (new MiniFloat()); //Zero } } else //Both are negative { MiniFloat r = add(m, n); r.Signbit = '1'; return(r); } }
/* Helper method, ignores sign-bits */ private static MiniFloat add(MiniFloat m, MiniFloat n) { MiniFloat result = new MiniFloat(); /* Need to be able to tell if it wraps over * I.E. 1.101 + 1.010 = 10.111 * Will have wrapped over if their lengths before hand are less than after */ result.Mantissa = m.Mantissa + n.Mantissa; result.Exponent = m.Exponent; //They've been normalized to the same exponent, doesn't matter /* If result is more bits than the longer of the two summands */ int longest = (m.Mantissa.Length >= n.Mantissa.Length) ? m.Mantissa.Length : n.Mantissa.Length; if (result.Mantissa.Length > longest) { int diff = result.Mantissa.Length - longest; //Should only ever be one but why not for (int i = 0; i < diff; i++) { result.Exponent += new Binary('1'); } } //else { //If the place before the decimal isn't two long //Take off leading one result.Mantissa.Body = result.Mantissa.Body.Substring(1); //} /* MiniFloat format can only hold 3 digits */ //result.MinimizeMantissa(); return(result); }
public MiniFloat Add(MiniFloat a, MiniFloat b) { if (b.exp > a.exp) { MiniFloat temp = a; a = b; b = temp; } BitArray A = a.Mantissa; BitArray B = b.Mantissa; BitArray Sum = new BitArray(A.Count); Boolean carry = false; B = ShiftRight(a.exp - b.exp, B, false); b.exp = a.exp; for (int i = A.Count - 1; i >= 0; i--) { // a(!b!c + bc) + !a(b!c + !bc) if ((A.Get(i) && ((!B.Get(i) && !carry) || (B.Get(i) && carry))) || (!A.Get(i) && ((B.Get(i) && !carry) || (!B.Get(i) && carry)))) { Sum.Set(i, true); } if ((A.Get(i) && (B.Get(i) || carry)) || (B.Get(i) && carry)) { carry = true; } else { carry = false; } } a.Mantissa = Sum; if (carry & !a.Sign & !b.Sign) { a.exp = a.exp + 1; a.Mantissa = ShiftRight(1, a.Mantissa, carry); } BitArray temp1 = new BitArray(4); while (!a.Mantissa.Get(0)) { for (int i = 0; i < a.Mantissa.Count - 1; i++) { temp1.Set(i, a.Mantissa.Get(i + 1)); } a.exp = a.exp - 1; a.Mantissa = temp1; } return(a); }
public static MiniFloat operator -(MiniFloat Minuend, MiniFloat Subtrahend) { MiniFloat m = Minuend.Copy(); MiniFloat n = Subtrahend.Copy(); /* To subtract, you add the negative */ n.Signbit = (n.Signbit == '0') ? '1' : '0'; //flip dat bit return(m + n); //+ operator deals with the signbit stuff }
public MiniFloat Multiply(MiniFloat a, MiniFloat b) { BitArray multiplier = a.Mantissa; BitArray multiplicand = b.Mantissa; BitArray Product = new BitArray(7); BitArray Sum = new BitArray(7); for (int i = 3; i >= 0; i--) { BitArray temp1 = new BitArray(7); if (multiplier.Get(i)) { Boolean carry = false; for (int k = 3; k <= 0; k--) { temp1.Set(i + k, multiplicand.Get(k)); } for (int j = temp1.Count - 1; i >= 0; i--) { // a(!b!c + bc) + !a(b!c + !bc) if ((temp1.Get(j) && ((!Product.Get(j) && !carry) || (Product.Get(j) && carry))) || (!temp1.Get(i) && ((Product.Get(i) && !carry) || (!Product.Get(j) && carry)))) { Sum.Set(i, true); } if ((temp1.Get(j) && (Product.Get(j) || carry)) || (Product.Get(j) && carry)) { carry = true; } else { carry = false; } } if (carry) { Sum = ShiftRight(1, Sum, carry); exp = exp + 1; } Product = new BitArray(Sum); } } for (int i = 3; i <= 0; i--) { a.Mantissa.Set(i, Product.Get(6 - i)); } a.exp = a.exp + b.exp; return(a); }
private static MiniFloat sub(MiniFloat m, MiniFloat n) { MiniFloat result; if (m.Mantissa > n.Mantissa) { result = new MiniFloat((m.Signbit == '1') ? '1' : '0'); } else if (n.Mantissa > m.Mantissa) { result = new MiniFloat((n.Signbit == '1') ? '1' : '0'); } else { result = new MiniFloat('0'); } try { result.Mantissa = m.Mantissa - n.Mantissa; result.Exponent = m.Exponent; } catch (BinaryUnderFlowException) { result.Signbit = (result.Signbit == '0') ? '1' : '0'; //Flip the sign result.Mantissa = n.Mantissa - m.Mantissa; } if (result.Mantissa.Body.IndexOf('1') != -1) // If there's a one in the mantissa { while (result.Mantissa[0] != '1') { result.ShiftDown(); } /* Take off leading one */ result.Mantissa.Body = result.Mantissa.Body.Substring(1); } //result.MinimizeMantissa(); return(result); }
private static void Normalize(ref MiniFloat a, ref MiniFloat b) { int diff = Convert.ToInt32(a.Exponent.BaseChange()) - Convert.ToInt32(b.Exponent.BaseChange()); //If b's exponent is bigger, will be < 0. if (diff < 0) { for (int i = 0; i < Math.Abs(diff); i++) { a.ShiftUp(); } } else if (diff > 0) { for (int i = 0; i < Math.Abs(diff); i++) { b.ShiftUp(); } } //If there's no difference then don't bother shifting diff = a.Mantissa.Length - b.Mantissa.Length; //Difference in their lengths //Reuse 'diff' // I.E. 1.010 vs 0.01101 will be 4 - 6 = 2, therefore a needs 2 zeros added if diff = -2 if (diff < 0) { for (int i = 0; i < Math.Abs(diff); i++) { a.Mantissa += '0'; } } else if (diff > 0) { for (int i = 0; i < Math.Abs(diff); i++) { b.Mantissa += '0'; } } }
static void Main(string[] args) { // addition // example 1: Console.WriteLine("addition examples"); Console.WriteLine("0.375 + 0.25 = 0.625"); MiniFloat a = new MiniFloat(false, 0, 3); Console.WriteLine(a.ToDouble(a)); MiniFloat b = new MiniFloat(false, 0, 2); Console.WriteLine(b.ToDouble(b)); MiniFloat c = a.Add(a, b); Console.WriteLine(c.ToDouble(c)); Console.WriteLine(" "); // example 2 Console.WriteLine("1.25 + 0.75 = 2"); a = new MiniFloat(false, 1, 5); Console.WriteLine(a.ToDouble(a)); b = new MiniFloat(false, 0, 6); Console.WriteLine(b.ToDouble(b)); c = a.Add(a, b); Console.WriteLine(c.ToDouble(c)); Console.WriteLine(" "); // example 3 Console.WriteLine("3 + 1 = 4"); a = new MiniFloat(false, 3, 3); Console.WriteLine(a.ToDouble(a)); b = new MiniFloat(false, 1, 4); Console.WriteLine(b.ToDouble(b)); c = a.Add(a, b); Console.WriteLine(c.ToDouble(c)); Console.WriteLine(" "); // Subtraction // example 1: Console.WriteLine("subtraction examples"); Console.WriteLine("0.25 -0.375 = -0.125"); a = new MiniFloat(true, 0, 3); Console.WriteLine(a.ToDouble(a)); b = new MiniFloat(false, 0, 2); Console.WriteLine(b.ToDouble(b)); c = a.Add(a, b); Console.WriteLine(c.ToDouble(c)); Console.WriteLine(" "); // example 2 Console.WriteLine("0.75-1.25 = -0.5"); a = new MiniFloat(true, 1, 5); Console.WriteLine(a.ToDouble(a)); b = new MiniFloat(false, 0, 6); Console.WriteLine(b.ToDouble(b)); c = a.Add(a, b); Console.WriteLine(c.ToDouble(c)); Console.WriteLine(" "); // example 3 Console.WriteLine("1-3 = -2"); a = new MiniFloat(true, 3, 3); Console.WriteLine(a.ToDouble(a)); b = new MiniFloat(false, 1, 4); Console.WriteLine(b.ToDouble(b)); c = a.Add(a, b); Console.WriteLine(c.ToDouble(c)); Console.WriteLine(" "); // Multiplication // example 1: Console.WriteLine("multiplication examples"); Console.WriteLine("0.25*0.375 = 0.09375"); a = new MiniFloat(false, 0, 3); Console.WriteLine(a.ToDouble(a)); b = new MiniFloat(false, 0, 2); Console.WriteLine(b.ToDouble(b)); c = a.Multiply(a, b); Console.WriteLine(c.ToDouble(c)); Console.WriteLine(" "); // example 2 Console.WriteLine("01.5*2 = 3"); a = new MiniFloat(false, 1, 6); Console.WriteLine(a.ToDouble(a)); b = new MiniFloat(false, 2, 4); Console.WriteLine(b.ToDouble(b)); c = a.Multiply(a, b); Console.WriteLine(c.ToDouble(c)); Console.WriteLine(" "); // example 3 Console.WriteLine("1*-3 = -3"); a = new MiniFloat(true, 3, 3); Console.WriteLine(a.ToDouble(a)); b = new MiniFloat(false, 1, 4); Console.WriteLine(b.ToDouble(b)); c = a.Multiply(a, b); Console.WriteLine(c.ToDouble(c)); Console.WriteLine(" "); // Division // example 1: Console.WriteLine("Divison examples"); Console.WriteLine("0.25*0.375 = 0.09375"); a = new MiniFloat(false, 4, 1); Console.WriteLine(a.ToDouble(a)); b = new MiniFloat(false, 3, 7); Console.WriteLine(b.ToDouble(b)); c = a.Divide(b, a); Console.WriteLine(c.ToDouble(c)); Console.WriteLine(" "); // example 2 Console.WriteLine("01.5*2 = 3"); a = new MiniFloat(false, 2, 1); Console.WriteLine(a.ToDouble(a)); b = new MiniFloat(false, 3, 7); Console.WriteLine(b.ToDouble(b)); c = a.Divide(a, b); Console.WriteLine(c.ToDouble(c)); Console.WriteLine(" "); // example 3 Console.WriteLine("1*-3 = -3"); a = new MiniFloat(false, 3, 3); Console.WriteLine(a.ToDouble(a)); b = new MiniFloat(false, 3, 1); Console.WriteLine(b.ToDouble(b)); c = a.Divide(a, b); Console.WriteLine(c.ToDouble(c)); Console.WriteLine(" "); // i had it working then it idk Console.ReadLine(); }
public MiniFloat Divide(MiniFloat a, MiniFloat b) { /// if more bits of percision exp = -exp mantissa = 1.0101010101010101010101 multiply? /// BitArray multiplier = a.Mantissa; BitArray Quotient = new BitArray(4); BitArray Divisor = new BitArray(9); BitArray Remainer = new BitArray(9); //gets f****d up cuz i normalized the mantisa when i created the float so the divisor and remander dont get set right for (int i = 0; i < 3; i++) { Divisor.Set(i, b.Mantissa.Get(i)); Remainer.Set(4 + i, a.Mantissa.Get(i)); } for (int i = 0; i < 4; i++) { BitArray CompDivisor = Compliment(new BitArray(Divisor)); BitArray Sum = new BitArray(9); Boolean carry = false; // subtract divisor from remainder for (int j = Divisor.Count - 1; j >= 0; j--) { // a(!b!c + bc) + !a(b!c + !bc) if ((CompDivisor.Get(j) && ((!Remainer.Get(j) && !carry) || (Remainer.Get(j) && carry))) || (!CompDivisor.Get(i) && ((Remainer.Get(i) && !carry) || (!Remainer.Get(j) && carry)))) { Sum.Set(i, true); } if ((CompDivisor.Get(j) && (Remainer.Get(j) || carry)) || (Remainer.Get(j) && carry)) { carry = true; } else { carry = false; } } // test remainder if (!Sum.Get(0)) { // R >= 0 shift Quotient left set rightmost to 1; for (int k = 0; k <= 2; k++) { Quotient.Set(k, Quotient.Get(k + 1)); } Quotient.Set(3, true); Remainer = new BitArray(Sum); } else { // restore remainder to initial value and shift left setting rightmost bit to 1 for (int k = 0; k <= 2; k++) { Quotient.Set(k, Quotient.Get(k + 1)); } Quotient.Set(3, false); } // shift divisor registar 1 bit; Divisor = ShiftRight(1, Divisor, false); } a.Mantissa = new BitArray(Quotient); a.exp = a.exp - b.exp; return(a); }
public static void Main(string[] args) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("-------------- Regular Binary Math --------------\n"); Console.ResetColor(); Binary a = new Binary("1101"); Binary b = new Binary("1011"); Binary[] binaryResults = new Binary[] { a + b, a - b, a *b, a / b }; char[] signs = { '+', '-', '*', '/' }; for (int i = 0; i < binaryResults.Length; i++) { Console.WriteLine("{0,4} {1} {2,4} = {3,8}", a, signs[i], b, binaryResults[i]); Console.ForegroundColor = ConsoleColor.DarkYellow; Console.WriteLine("{0,4} {1} {2,4} = {3,8}\n", a.BaseChange(), signs[i], b.BaseChange(), binaryResults[i].BaseChange()); Console.ResetColor(); } Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("\n-------------- MiniFloat Math -------------------\n"); for (int k = 0; k < 3; k++) { for (int i = 0; i < 2; i++) { MiniFloat x; MiniFloat y; switch (k) { case 1: /* Example 2 */ x = new MiniFloat('0', "0111", "101"); y = new MiniFloat('0', "1001", "010"); break; case 2: /* Example 3 */ x = new MiniFloat('0', "1010", "110"); y = new MiniFloat('0', "1001", "110"); break; default: /* Example 1*/ x = new MiniFloat('1', "1011", "101"); y = new MiniFloat('0', "0111", "011"); break; } if (i == 0) { Console.ForegroundColor = ConsoleColor.DarkRed; Console.WriteLine("-------- {0,10} and {1,10} -----------\n", x, y); Console.ResetColor(); } MiniFloat[] miniFloatResults = new MiniFloat[] { x + y, x - y, x *y, x / y }; Console.ForegroundColor = ConsoleColor.Blue; if (i == 0) { Console.WriteLine("------------ Without Rounding ------------\n"); } else { Console.WriteLine("\n------------ With Rounding ---------------\n"); x.MinimizeMantissa(); y.MinimizeMantissa(); foreach (MiniFloat m in miniFloatResults) { m.MinimizeMantissa(); } } Console.ResetColor(); for (int j = 0; j < miniFloatResults.Length; j++) { Console.WriteLine("{0} {1} {2} = {3}", x, signs[j], y, miniFloatResults[j]); Console.ForegroundColor = ConsoleColor.DarkYellow; Console.WriteLine("{0,10} {1} {2,10} = {3,10}\n", x.BaseChange(), signs[j], y.BaseChange(), miniFloatResults[j].BaseChange()); Console.ResetColor(); } } } Console.ReadLine(); }