divide method
Implementation
UcumDecimal divide(UcumDecimal other) {
if (isZero()) {
return zero();
} else if (other.isZero()) {
throw UcumException('Attempt to divide $toString() by zero');
} else {
final String s = '0${other.digits}';
final int m = math.max(digits.length, other.digits.length) +
40; // max loops we'll do
final List<String> tens = List<String>.filled(10, '');
tens[0] = stringAddition(stringMultiply('0', s.length), s);
for (int i = 1; i < 10; i++) {
tens[i] = stringAddition(tens[i - 1], s);
}
String v = digits;
String r = '';
int l = 0;
int d = (digits.length - decimal + 1) -
(other.digits.length - other.decimal + 1);
while (v.length < tens[0].length) {
v = '${v}0';
d++;
}
String w;
int vi;
if (v.substring(0, other.digits.length).compareTo(other.digits) < 0) {
if (v.length == tens[0].length) {
v = '${v}0';
d++;
}
w = v.substring(0, other.digits.length + 1);
vi = w.length;
} else {
w = '0${v.substring(0, other.digits.length)}';
vi = w.length - 1;
}
bool handled = false;
bool proc;
while (!(handled &&
((l > m) ||
((vi >= v.length) && (Utilities.noString(w) || allZeros(w)))))) {
l++;
handled = true;
proc = false;
for (int i = 8; i >= 0; i--) {
if (tens[i].compareTo(w) <= 0) {
proc = true;
r = r + cdig(i + 1);
w = trimLeadingZeros(stringSubtraction(w, tens[i]));
if (!(handled &&
((l > m) ||
((vi >= v.length) &&
(Utilities.noString(w) || allZeros(w)))))) {
if (vi < v.length) {
w = w + v[vi];
vi++;
handled = false;
} else {
w = '${w}0';
d++;
}
while (w.length < tens[0].length) {
w = '0$w';
}
}
break;
}
}
if (!proc) {
assert(w[0] == '0');
w = delete(w, 0, 1);
r = '${r}0';
if (!(handled &&
((l > m) ||
((vi >= v.length) &&
(Utilities.noString(w) || allZeros(w)))))) {
if (vi < v.length) {
w = w + v[vi];
vi++;
handled = false;
} else {
w = '${w}0';
d++;
}
while (w.length < tens[0].length) {
w = '0$w';
}
}
}
}
int prec;
if (isWholeNumber() && other.isWholeNumber() && (l < m)) {
for (int i = 0; i < d; i++) {
if (r[r.length - 1] == '0') {
r = delete(r, r.length - 1, 1);
d--;
}
}
prec = 100;
} else {
if (isWholeNumber() && other.isWholeNumber()) {
prec = math.max(digits.length, other.digits.length);
} else if (isWholeNumber()) {
prec = math.max(other.precision, r.length - d);
} else if (other.isWholeNumber()) {
prec = math.max(precision, r.length - d);
} else {
prec = math.max(math.min(precision, other.precision), r.length - d);
}
if (r.length > prec) {
d = d - (r.length - prec);
final int digit = r[prec].codeUnitAt(0);
final bool up = digit >= '5'.codeUnitAt(0);
if (up) {
final List<int> rs = r.substring(0, prec).codeUnits.toList();
int i = rs.length - 1;
bool carry = true;
while (carry && i >= 0) {
int ls = rs[i];
if (ls == '9'.codeUnitAt(0)) {
rs[i] = '0'.codeUnitAt(0);
} else {
ls = ls + 1;
rs[i] = ls;
carry = false;
}
i--;
}
if (carry) {
r = '1${String.fromCharCodes(rs)}';
d++; // because we added one at the start
} else {
r = String.fromCharCodes(rs);
}
} else {
r = r.substring(0, prec);
}
}
}
final UcumDecimal result = UcumDecimal();
result.setValueUcumDecimal(r);
result.decimal = r.length - d;
result.negative = negative != other.negative;
result.precision = prec;
result.scientific = scientific || other.scientific;
return result;
}
}