Example #1
0
        /// <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();
        }
Example #2
0
        /// <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);
        }