internal Combo(Unit a, String op, Unit b) { this.a = a; this.op = op; this.b = b; }
private static Unit findMult(Unit a, Unit b) { // compute dim/scale of a * b Dimension dim = a.m_dim.add(b.m_dim).intern(); double scale = a.m_scale * b.m_scale; // find all the matches Unit[] matches = match(dim, scale); if (matches.Length == 1) return matches[0]; // right how our technique for resolving multiple matches is lame string expectedName = a.name() + "_" + b.name(); for (int i=0; i<matches.Length; ++i) if (matches[i].name() == expectedName) return matches[i]; // for now just give up throw Err.make("Cannot match to db: " + a + " * " + b).val; }
////////////////////////////////////////////////////////////////////////// // Arithmetic ////////////////////////////////////////////////////////////////////////// public Unit mult(Unit b) { lock (m_combos) { Combo key = new Combo(this, "*", b); Unit r = (Unit)m_combos[key]; if (r == null) { r = findMult(this, b); m_combos[key] = r; } return r; } }
public Unit findDiv(Unit a, Unit b) { // compute dim/scale of a / b Dimension dim = a.m_dim.subtract(b.m_dim).intern(); double scale = a.m_scale / b.m_scale; // find all the matches Unit[] matches = match(dim, scale); if (matches.Length == 1) return matches[0]; // right how our technique for resolving multiple matches is lame string expectedName = a.name() + "_per_" + b.name(); for (int i=0; i<matches.Length; ++i) if (matches[i].name().Contains(expectedName)) return matches[i]; // for now just give up throw Err.make("Cannot match to db: " + a + " / " + b).val; }
public Unit div(Unit b) { lock (m_combos) { Combo key = new Combo(this, "/", b); Unit r = (Unit)m_combos[key]; if (r == null) { r = findDiv(this, b); m_combos[key] = r; } return r; } }
////////////////////////////////////////////////////////////////////////// // Conversion ////////////////////////////////////////////////////////////////////////// public double convertTo(double scalar, Unit to) { if (m_dim != to.m_dim) throw Err.make("Incovertable units: " + this + " and " + to).val; return ((scalar * this.m_scale + this.m_offset) - to.m_offset) / to.m_scale; }