normaliseTerm method

Canonical normaliseTerm(
  1. String indent,
  2. Term term
)

Implementation

Canonical normaliseTerm(String indent, Term term) {
  final Canonical result =
      Canonical(UcumDecimal.fromString('1.000000000000000000000000000000'));

  debugTerm(indent, 'canonicalise', term);
  bool div = false;
  Term? t = term;
  while (t != null) {
    if (t.comp is Term) {
      final Canonical temp = normaliseTerm('$indent  ', t.comp! as Term);
      if (div) {
        result.value = result.value.divide(temp.value);
        for (final CanonicalUnit c in temp.units) {
          c.exponent = -c.exponent;
        }
      } else {
        result.value = result.value.multiply(temp.value);
      }
      result.units.addAll(temp.units);
    } else if (t.comp is Factor) {
      if (div) {
        result.value = result.value.divideInt((t.comp! as Factor).value);
      } else {
        result.value = result.value.multiplyInt((t.comp! as Factor).value);
      }
    } else if (t.comp is Symbol) {
      final Symbol o = t.comp! as Symbol;
      final Canonical temp = normaliseSymbol(indent, o);
      if (div) {
        result.value = result.value.divide(temp.value);
        for (final CanonicalUnit c in temp.units) {
          c.exponent = -c.exponent;
        }
      } else {
        result.value = result.value.multiply(temp.value);
      }
      result.units.addAll(temp.units);
    }
    div = t.op == Operator.division;
    t = t.term;
  }

  debugCanonical(indent, 'collate', result);

  for (int i = result.units.length - 1; i >= 0; i--) {
    final CanonicalUnit sf = result.units[i];
    for (int j = i - 1; j >= 0; j--) {
      final CanonicalUnit st = result.units[j];
      if (st.base == sf.base) {
        st.exponent = sf.exponent + st.exponent;
        result.units.removeAt(i);
        break;
      }
    }
  }

  for (int i = result.units.length - 1; i >= 0; i--) {
    if (result.units[i].exponent == 0) {
      result.units.removeAt(i);
    }
  }

  debugCanonical(indent, 'sort', result);
  result.units.sort((CanonicalUnit lhs, CanonicalUnit rhs) =>
      lhs.base.code.compareTo(rhs.base.code));
  debugCanonical(indent, 'done', result);

  return result;
}