mirror of https://github.com/rm-dr/daisy
Fixed unit matching
parent
7fb0e0274c
commit
7b77c49ba4
|
@ -111,7 +111,6 @@ impl Quantity {
|
|||
return Some(n.mul_no_convert(fa).div_no_convert(fb))
|
||||
}
|
||||
|
||||
|
||||
pub fn match_units(&mut self, other: &Quantity) {
|
||||
|
||||
let mut new_units = Quantity::new_rational_from_string("1").unwrap();
|
||||
|
@ -123,14 +122,15 @@ impl Quantity {
|
|||
|
||||
// Check if `us` matches some unit in `other`
|
||||
for (uo, _) in other.unit.get_val() {
|
||||
if {
|
||||
uo.to_base().unit.compatible_with(&us.to_base().unit)
|
||||
} {
|
||||
// If it does, convert `us` to `uo`
|
||||
new_units.insert_unit(uo.clone(), ps.clone());
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
// Use generalized compatible_with check to match reciprocal units
|
||||
// (for example, 1Hz * 1 sec.)
|
||||
let f = uo.to_base().unit.compatible_with_power(&us.to_base().unit);
|
||||
if f.is_none() { continue; }
|
||||
let f = f.unwrap();
|
||||
|
||||
new_units.insert_unit(uo.clone(), ps.clone() * f);
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
if !flag {
|
||||
// If no unit in `other` matches `us`, don't convert `us`
|
||||
|
|
|
@ -162,6 +162,55 @@ impl Unit {
|
|||
return o == s;
|
||||
}
|
||||
|
||||
|
||||
// True if all base units are the same AND there is a constant factor between their powers.
|
||||
// This is a generalization of `compatible_with`. `compatible_with` is true iff
|
||||
// `compatible_with_power` is one.
|
||||
pub fn compatible_with_power(&self, other: &Unit) -> Option<Scalar> {
|
||||
let mut flag;
|
||||
let mut pow_factor: Option<Scalar> = None;
|
||||
|
||||
let sbu = self.to_base().unit;
|
||||
let obu = other.to_base().unit;
|
||||
|
||||
for (us, ps) in sbu.get_val() {
|
||||
flag = false;
|
||||
for (uo, po) in obu.get_val() {
|
||||
if uo.whole == us.whole {
|
||||
if pow_factor.is_none() {
|
||||
pow_factor = Some(po.clone() / ps.clone());
|
||||
} else if let Some(ref f) = pow_factor {
|
||||
if *f != po.clone() / ps.clone() { return None; }
|
||||
}
|
||||
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if !flag { return None; }
|
||||
}
|
||||
|
||||
pow_factor = None;
|
||||
for (uo, po) in obu.get_val() {
|
||||
flag = false;
|
||||
for (us, ps) in sbu.get_val() {
|
||||
if uo.whole == us.whole {
|
||||
if pow_factor.is_none() {
|
||||
pow_factor = Some(po.clone() / ps.clone());
|
||||
} else if let Some(ref f) = pow_factor {
|
||||
if *f != po.clone() / ps.clone() { return None; }
|
||||
}
|
||||
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if !flag { return None; }
|
||||
}
|
||||
|
||||
return pow_factor;
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, u: FreeUnit, p: Scalar) {
|
||||
let v = self.get_val_mut();
|
||||
match v.get_mut(&u) {
|
||||
|
|
|
@ -211,4 +211,6 @@ fn complex_units() {
|
|||
good_expr("20 mi", "10 mph * 2 hours");
|
||||
good_expr("120 m", "1 (m/s) * 2 min");
|
||||
good_expr("120 m", "(2 min) * (1 m/s)");
|
||||
good_expr("180", "1 Hz * 3 min");
|
||||
good_expr("3600", "1 hour * 1 Hz");
|
||||
}
|
Loading…
Reference in New Issue