Mindshift: Part 18

Subtraction Using Addition

Now that we can work out the SUCCessor and PREDecessor of our special signed functions, we are now in a position to look at performing simple arithmetic functions such as ADD and SUBTRACT.

How Does Addition Currently Work?

Previously, when we used a "naked" abstract quantity function to represent and unsigned integers, addition and subtraction were easy - as long as the result was a positive integer.

If we take another look at the calculations used for unsigned integers, then the addition of two quantity functions a and b was simply a matter of finding the b'th SUCCessor of a. Similarly, as long as the answer was greater than or equal to 0, subtracting b from a required us to find the b'th PREDecessor of a.

Here's how we previously did addition:

Well, that's easy enough...

The Sign Points The Way!

However, now we are no longer dealing with "naked" quantity functions. Instead, we are dealing with a PAIR formed from a Boolean sign and an abstract quantity function (the magnitude).

Therefore, when we start adding and subtracting these PAIRs, we must take into account the sign of the number and then add or subtract as necessary.

The limitation with our previous ADD and SUBTRACT functions is that they cannot perform any calculation that requires passing through 0 - and this limitation isn't going to go away simply because we've added a sign to the front of an integer. However, this will not stop us being able to perform all the needed calculations.

So when we subtract 5 from 3, we expect to get the answer -2; however, if we attempted this calculation using the current definition of SUBTRACT, all we would get is 0.

However, we can also obtain the correct answer by recognising that 5 is greater than 3. So we flip the subtraction around (5 - 3 = +2) and return the result as a negative number, thus giving the required -2.

So addition and subtraction now become slightly more complicated in that we first need to test whether the two numbers have same sign, and secondly, if the signs are different, we must subtract the smaller operand from the larger.

Let's write out how the different combinations of signs should be handled. The table below shows numbers as they are represented in our abstract NUMBER function; that is, as a PAIR formed from a Boolean sign and a magnitude (or absolute value).

Addition of PAIRs
Operand 1 Operand 2 Returns
(+)(n1) (+)(n2) (+)(n1+n2)
(-)(n1) (-)(n2) (-)(n1+n2)
(+)(n1) (-)(n2) if (n2) <= (n1)
then (+)(n1-n2)
else (-)(n2-n1)
(-)(n1) (+)(n2) if (n1) <= (n2)
then (+)(n2-n1)
else (-)(n1-n2)



One striking thing to notice about this table is that even though we are calling this operation ADD, we are actually more likely to subtract the two operands than add them. If fact, the only time we perform an addition is when both operands have the same sign. The rest of the time we're subtracting!

Reuse Our Existing ADD and SUBTRACT functions

Since we still need to add and subtract abstract quantity functions, the functionality contained within our existing ADD and SUBTRACT functions is still going to be needed; however, we must rename these functions to better describe what they do.

So ADD becomes ADD_MAGNITUDES and SUBTRACT becomes SUBTRACT_MAGNITUDES.

See the previous blog Mindshift: Part 17 for a definition of the SUCC_MAGNITUDE and PRED_MAGNITUDE functions.

If you look in the table above, when we try to add two numbers having different signs, we need a "less than or equal to" operator. So let's define this too:

Notice that function IS_LTE takes two NUMBERs as parameters rather than two quantity functions. Again, see Mindshift: Part 17 for a definition of the HAS_ZERO_MAGNITUDE function.

Building the ADD Function

Now we are in a position to implement the table shown above as the new version of the ADD function.

Well that's a little more complicated than our previous version of ADD, but this is because we must now take into account first the numbers' signs, and second, whether one number is bigger than the other.

Good, that works.

So, Is Subtraction Just As Complicated?

Fortunately, the answer is no because we know that the subtraction operation 5 - 3 is equivalent to the addition operation 5 + (-3).

Just to demonstrate this to ourselves, lets write out the four permutations of signs in a subtraction operation, and their equivalent addition operation.

Equivalence of Subtraction and Addition operations
Subtraction Is the same as
(+)(n1) - (+)(n2) (+)(n1) + (-)(n2)
(+)(n1) - (-)(n2) (+)(n1) + (+)(n2)
(-)(n1) - (+)(n2) (-)(n1) + (-)(n2)
(-)(n1) - (-)(n2) (-)(n1) + (+)(n2)



So all we need to do to here is flip the sign of the second operand and subtraction can be performed using addition. Therefore, the new version of function SUBTRACT becomes an interface to function ADD:

All we're doing inside function SUBTRACT is to call ADD using the first parameter num1 unmodified, and constructing a new number from num2 using the NOT of its sign and its absolute value.

So there we have it - the ability to perform subtraction using only the addition operator.

In the next blog, we'll look at multiplication and division.

Chris W


All source code from the Mindshift blog series can be found on GitHub