public void Subtract(BigInteger bi) {
AssertValid();
bi.AssertValid();
Debug.Assert((object)this != (object)bi);
int idx;
uint wCarry, uT;
if (length < bi.length) {
goto LNegative;
}
wCarry = 1;
for (idx = 0; idx < bi.length; idx++) {
Debug.Assert(0 == wCarry || 1 == wCarry);
uT = bi.digits[idx];
// NOTE: We should really do:
// wCarry = AddU(ref digits[idx], wCarry);
// wCarry += AddU(ref digits[idx], ~uT);
// The only case where this is different than
// wCarry = AddU(ref digits[idx], ~uT + wCarry);
// is when 0 == uT and 1 == wCarry, in which case we don't
// need to add anything and wCarry should still be 1, so we can
// just skip the operations.
if (0 != uT || 0 == wCarry) {
wCarry = AddU(ref digits[idx], ~uT + wCarry);
}
}
while (0 == wCarry && idx < length) {
wCarry = AddU(ref digits[idx], 0xFFFFFFFF);
}
if (0 != wCarry) {
if (idx == length) {
// Trim off zeros.
while (--idx >= 0 && 0 == digits[idx]) {
}
length = idx + 1;
}
AssertValid();
return;
}
LNegative:
// bi was bigger than this.
Debug.Assert(false, "Who's subtracting to negative?");
length = 0;
AssertValid();
}