sub method
Return a new Big whose value is the value of this Big minus the value of Big y.
Implementation
Big sub(dynamic y) {
var yBig = Big(y);
int i, j;
List<int> t;
var x = this, a = x.s, b = yBig.s;
bool isXLtY;
// Signs differ?
if (a != b) {
yBig.s = -b;
return x.add(yBig);
}
var xc = [...x.c], xe = x.e, yc = yBig.c, ye = yBig.e;
// Either zero?
if (!xc.isElementIsValid(0) || !yc.isElementIsValid(0)) {
if (yc.isElementIsValid(0)) {
yBig.s = -b;
} else if (xc.isElementIsValid(0)) {
yBig = Big(x);
} else {
yBig.s = 1;
}
return yBig;
}
a = xe - ye;
// Determine which is the bigger number. Prepend zeros to equalise exponents.
if (a != 0) {
if (isXLtY = a < 0) {
a = -a;
t = xc;
} else {
ye = xe;
t = yc;
}
t.reverse();
for (b = a; b > 0;) {
b--;
t.add(0);
}
t.reverse();
} else {
// Exponents equal. Check digit by digit.
j = ((isXLtY = xc.length < yc.length) ? xc : yc).length;
for (a = b = 0; b < j; b++) {
if (xc[b] != yc[b]) {
isXLtY = xc[b] < yc[b];
break;
}
}
}
// x < y? Point xc to the array of the bigger number.
if (isXLtY) {
t = xc;
xc = yc;
yc = t;
yBig.s = -yBig.s;
}
/// Append zeros to xc if shorter. No need to add zeros to yc if shorter as subtraction only
/// needs to start at yc.length.
if ((b = (j = yc.length) - (i = xc.length)) > 0) {
for (; b > 0;) {
b--;
i++;
xc.add(0);
}
}
// Subtract yc from xc.
for (b = i; j > a;) {
if (xc[--j] < yc[j]) {
for (i = j; i > 0 && !xc.isElementIsValid(--i);) {
xc[i] = 9;
}
--xc[i];
xc[j] += 10;
}
xc[j] -= yc[j];
}
// Remove trailing zeros.
for (; xc[--b] == 0;) {
xc.removeLast();
if (b == 0) {
break;
}
}
// Remove leading zeros and adjust exponent accordingly.
for (; xc.isNotEmpty && xc[0] == 0;) {
xc.removeAt(0);
--ye;
}
if (!xc.isElementIsValid(0)) {
// n - n = +0
yBig.s = 1;
// Result must be zero.
xc = [ye = 0];
}
yBig.c = xc;
yBig.e = ye;
return yBig;
}