I am writing a simple BigInteger type in Delphi. This type consist of an array of unsigned 32 bit integers (I call them limbs), a count (or size) and a sign bit. The value in the array is interpreted as absolute value, so this is a sign-magnitude representation. This has several advantages, but one disadvantage.
The bitwise operations like and
, or
, xor
and not
have two's complement semantics. This is no problem if both BigInteger
s have positive values, but the magnitudes of negative BigInteger
s must be converted to two's complement by negation. This can be a performance problem, since if we do, say
C := -A and -B;
then I must negate the magnitudes of A
and B
before the and
operation can be performed. Since the result is supposed to be negative too, I must negate the result too to get a positive magnitude again. For large BigInteger
s, negating up to three values can be a considerable performance cost.
Mind you, I know how to do this and the results are correct, but I want to avoid the slowness caused by the necessary negations of large arrays.
I know of a few shortcuts, for instance
C := not A;
can be achieved by calculating
C := -1 - A;
which is what I do, and the result is fine. This makes not
as performant as addition or subtraction, since it avoids the negation before (and after) the operation.
Question
My question is: are there similar laws I can use to avoid negating the magnitudes of "negative" BigInteger
s? I mean something like the calculation of not
by using subtraction?
I mean simple or not-so-simple laws like
not A and not B = not (A or B) // = is Pascal for ==
not A or not B = not (A and B)
but then for -A and/or -B, etc. I do know that
(-A and -B) <> -(A or B) // <> is Pascal for !=
is not true, but perhaps there is something similar?
I simply can't find any such laws that relate to negative values and bitwise operations, if they exist at all. Hence my question.