private eeNumber IntegerDivision(eeNumber divisor, out eeNumber mod) { // base case if (this.AbsoluteValue() < divisor.AbsoluteValue()) { mod = this; return(new eeNumber(0)); } Queue <byte> bytesQue = new Queue <byte>(this.bytes); // a queue of the dividend as bytes List <eeNumber> quotient = new List <eeNumber>(); // quotient eeNumber divPart = null; while (bytesQue.Count() > 0) { /* Grab the next digit from dividend */ var asList = divPart == null ? new List <byte>() : divPart.bytes.ToList(); var nextByte = bytesQue.Dequeue(); asList.Add(nextByte); /* Keep grabbing until we run out or need more */ divPart = new eeNumber(asList); while (bytesQue.Count() != 0 && divPart < divisor) { quotient.Add(new eeNumber(0)); asList.Add(bytesQue.Dequeue()); divPart = new eeNumber(asList); divPart.TrimZeros(); } divPart.TrimZeros(); /* Divide it and append the division to the quotient */ eeNumber q = new eeNumber(1); // number of times divisor fits into this divPart while (divisor * q <= divPart) { q += ONE; } q -= ONE; quotient.Add(q); // keep track of quotient /* Figure out the remainder*/ divPart = divPart - (divisor * q); } // remainder mod = divPart; var intergerQuotient = new eeNumber(quotient); intergerQuotient.TrimZeros(); return(intergerQuotient); }
// Warning: Subtraction will destroy the contents of num2 and set the contents of num1 to the result // Make sure to pass a copy of num2 if you are keeping its value public static eeNumber operator -(eeNumber num1_orig, eeNumber num2_orig) { eeNumber num1 = num1_orig.Copy(), num2 = num2_orig.Copy(); // If either number is a fraction, cross multiply if (num1.IsFrac() || num2.IsFrac()) { eeNumber frac1 = num1.PopDenominator(), frac2 = num2.PopDenominator(); num1 *= frac2; num2 *= frac1; var ret = (num1 - num2) / (frac1 * frac2); ret.TrimZeros(); ret.Simplify(); return(ret); } // if the two nums are the same if (num1 == num2) { return(ZERO.Copy()); } // if first num is negative else if (num1.negative && !num2.negative) { // add them then negate it num1.negative = false; var sum = num1 + num2; sum.negative = true; return(sum); } // if second num is negative else if (num2.negative && !num1.negative) { // minus and negatives cancel num2.negative = false; return(num1 + num2); } // If they're both negative else if (num1.negative && num2.negative) { // Treat this as adding a negative to a positive num2.negative = false; return(num1 + num2); } // If we're going to get a negative answer bool negate = false; if (num2 > num1) { // reverse the two var buf = num1; num1 = num2; num2 = buf; // and negate negate = true; } // Reverse because we're subtracting from right to left. byte[] l_bytes = num1.bytes.Reverse().ToArray(), r_bytes = num2.bytes.Reverse().ToArray(); bool carry = false; int i; for (i = 0; i < r_bytes.Length; i++) { // Account for the previous carry if (carry) { r_bytes[i]++; carry = false; } // Subtract the digits byte digitDiff; if (l_bytes[i] < r_bytes[i]) // account for carry { digitDiff = (byte)((10 + l_bytes[i]) - r_bytes[i]); carry = true; } else { digitDiff = (byte)(l_bytes[i] - r_bytes[i]); } // Set the digit l_bytes[i] = digitDiff; } // If there is still carry left while (carry) { // subtract one from the next value if (l_bytes[i] == 0) { l_bytes[i] = 9; i++; } else { l_bytes[i] -= 1; carry = false; } } // Put it in order again l_bytes = l_bytes.Reverse().ToArray(); num1.bytes = l_bytes; num1.negative = negate; num1.TrimZeros(); return(num1); }