That should be fine, at least on a conceptual level. However, you need to be a little bit careful here.
The fact that the subtract routine is about the same size as the add routine could mean (at least) two things:
- the library writers did a poor job; or
- they did a good job but you don't yet realise it :-)
The reason I state this is because I've written multi-precision integer libraries in the past where, other than some delegation, the add and subtract routines could assume certain properties to allow for simplified code. So, for example, the (pseudo-) code would be something like (in the comments, +x
means x >= 0
, -x means
x < 0`):
def add(a, b):
if a <= 0:
if b <= 0:
return -add(-a, -b) # -a, -b.
return sub(b, -a) # -a, +b.
if b <= 0:
return sub(a, -b) # +a, -b.
# +a, +b, hence greatly simplified code.
def sub(a, b):
if a <= 0:
if b <= 0:
return -sub(-a, -b) # -a, -b.
return -add(-a, b) # -a, +b.
if b <= 0:
return add(a, -b) # +a, -b.
if a < b:
return -sub(b, a) # +a, +b, a < b.
# +a, +b, a >= b, hence greatly simplified code.
The comments to the right show the guaranteed conditions which make the if
condition true. Not all these are explicitly checked since, without them, an earlier if
statement would have been true and thew function would already have returned.
The "simplified code" area could then concentrate on doing its job knowing that the numbers it had were "safe". For example:
- It could do addition knowing that both numbers were non-negative, so it's a simple matter of starting at the right and adding digits with carry.
- It could do subtraction without having to worry that the second number was bigger than the first, something that results in an "infinite borrow" problem in naive implementations.
So, if your add and subtract routines are basically duplicates (i.e., the library writers did a poor job) without referencing each other (even indirectly through other calls), you will probably be able to save some space by using your method.
However, if the library writers were a bit cleverer than that, it may well be that they've done a delegation job similar to what I describe above. That means it would be a rather bad idea to replace sub
with something like what you are proposing:
def sub(a, b):
return add(a, -b)
That's because add(5, -1)
would almost delegate that call to sub(5, 1)
. Which would, of course, send it back to add(5, -1)
, and so on, right up until the point your stack overflows :-)
So, just be certain that these delegations do not happen before you assume that your method will work. Because this is the sort of thing a library writer should have put in their code (but see the "did a poor job" text above).