/// <summary> /// Performs an integer division, returning the quotient and remainder after division /// </summary> /// <param name="dividend"></param> /// <param name="divisor"></param> /// <param name="remainder"></param> /// <param name="quotient"></param> public static void LongDivision(BinaryNumber dividend, BinaryNumber divisor, out BinaryNumber remainder, out BinaryNumber quotient) { var modifiedDivisor = new BinaryNumber(divisor); remainder = new BinaryNumber(dividend); while (remainder > modifiedDivisor) { modifiedDivisor.RotateLeft(); } if (modifiedDivisor > remainder) { modifiedDivisor.RotateRight(); } quotient = new BinaryNumber(); while (remainder > divisor) { if (modifiedDivisor > remainder) { quotient.AddLast(false); } else { remainder -= modifiedDivisor; quotient.AddLast(true); } modifiedDivisor.RotateRight(); } quotient.Compact(); }
/// <summary> /// Performs an abstract operation on two numbers, returning the compacted result /// </summary> /// <param name="a">One binary number</param> /// <param name="b">The other binary number</param> /// <param name="bitwiseFn">A function with parameters a_i, b_i, state and returning an operation on those</param> /// <param name="stateFn">A function that calculates the new state based on a_i, b_i, and the state</param> /// <param name="remainderBitwiseFn">A function that returns an operation on r_i, state. r_i is a part of the remaining digits (when one binary number is longer than the other)</param> /// <param name="remainderStateFn">A function that calculates the state in the remainder case</param> /// <param name="followupFn">A function that can optionally include an additional digit based on the state after everything completes</param> /// <returns></returns> private static BinaryNumber Operate(BinaryNumber a, BinaryNumber b, Func <bool, bool, bool, bool> bitwiseFn, Func <bool, bool, bool, bool> stateFn, Func <bool, bool, bool> remainderBitwiseFn, Func <bool, bool, bool> remainderStateFn, Func <bool, bool> followupFn) { var result = new BinaryNumber(); var aNode = a.Last; var bNode = b.Last; var state = false; // Do the bitwise operation while (aNode != null && bNode != null) { // Calculate values var aI = aNode.Value; var bI = bNode.Value; var bitwiseResult = bitwiseFn != null?bitwiseFn(aI, bI, state) : false; state = stateFn != null?stateFn(aI, bI, state) : false; // Prepend the calculated value result.AddFirst(bitwiseResult); // Proceed aNode = aNode.Previous; bNode = bNode.Previous; } // Either a or b might be longer than the other, so extend the result with the remaining bits // At this point, only up to one of (aNode, bNode) is non-null if (bNode != null) { aNode = bNode; } // If either aNode or bNode were non-null, that node is now called "aNode". If they were both null then aNode is null while (aNode != null) { // Calculate values in the remainder case var rI = aNode.Value; var remainderResult = remainderBitwiseFn != null?remainderBitwiseFn(rI, state) : false; state = remainderStateFn != null?remainderStateFn(rI, state) : false; // Prepend the calculated value result.AddFirst(remainderResult); // Proceed aNode = aNode.Previous; } // Now do something with the remaining state bit result.AddFirst(followupFn(state)); // Finally, compact the result result.Compact(); return(result); }