Improved unit printing

pull/2/head
Mark 2023-04-09 08:39:22 -07:00
parent 2fb25fb742
commit e9645208d9
Signed by: Mark
GPG Key ID: AD62BB059C2AAEE4
6 changed files with 46 additions and 9 deletions

View File

@ -25,12 +25,13 @@ pub struct Quantity {
impl ToString for Quantity { impl ToString for Quantity {
fn to_string(&self) -> String { fn to_string(&self) -> String {
let mut n = self.v.to_string(); let n = self.v.to_string();
if self.unitless() { return n; } if self.unitless() { return n; }
n.push(' '); let u = self.u.to_string();
n.push_str(&self.u.to_string()); if self.is_one() { return u; };
return n;
return format!("{n} {u}");
} }
} }
@ -75,9 +76,8 @@ impl Quantity {
}); });
} }
pub fn add_unit(&mut self, ui: BaseUnit, pi: f64) { pub fn insert_unit(&mut self, ui: BaseUnit, pi: f64) { self.u.insert(ui, pi) }
self.u.insert(ui, pi) pub fn set_unit(&mut self, u: Unit) { self.u = u; }
}
} }
@ -96,6 +96,7 @@ macro_rules! quant_foward {
impl Quantity { impl Quantity {
pub fn is_zero(&self) -> bool { self.v.is_zero() } pub fn is_zero(&self) -> bool { self.v.is_zero() }
pub fn is_one(&self) -> bool { self.v.is_one() }
pub fn is_nan(&self) -> bool { self.v.is_nan() } pub fn is_nan(&self) -> bool { self.v.is_nan() }
pub fn is_negative(&self) -> bool { self.v.is_negative() } pub fn is_negative(&self) -> bool { self.v.is_negative() }
pub fn is_positive(&self) -> bool { self.v.is_positive() } pub fn is_positive(&self) -> bool { self.v.is_positive() }

View File

@ -48,6 +48,7 @@ impl ScalarBase for F64Base {
foward!(fract); foward!(fract);
fn is_zero(&self) -> bool {self.val == 0f64} fn is_zero(&self) -> bool {self.val == 0f64}
fn is_one(&self) -> bool {self.val == 1f64}
fn is_negative(&self) -> bool { self.val.is_sign_negative() } fn is_negative(&self) -> bool { self.val.is_sign_negative() }
fn is_positive(&self) -> bool { self.val.is_sign_positive() } fn is_positive(&self) -> bool { self.val.is_sign_positive() }

View File

@ -123,6 +123,7 @@ impl ScalarBase for FloatBase {
foward!(fract); foward!(fract);
fn is_zero(&self) -> bool {self.val.is_zero()} fn is_zero(&self) -> bool {self.val.is_zero()}
fn is_one(&self) -> bool {self.val == Float::with_val(FLOAT_PRECISION, 1)}
fn is_negative(&self) -> bool { self.val.is_sign_negative() } fn is_negative(&self) -> bool { self.val.is_sign_negative() }
fn is_positive(&self) -> bool { self.val.is_sign_positive() } fn is_positive(&self) -> bool { self.val.is_sign_positive() }

View File

@ -24,6 +24,7 @@ pub trait ScalarBase:
// Utility // Utility
fn fract(&self) -> Option<Self>; fn fract(&self) -> Option<Self>;
fn is_zero(&self) -> bool; fn is_zero(&self) -> bool;
fn is_one(&self) -> bool;
fn is_negative(&self) -> bool; fn is_negative(&self) -> bool;
fn is_positive(&self) -> bool; fn is_positive(&self) -> bool;
@ -163,6 +164,13 @@ impl Scalar {
} }
} }
pub fn is_one(&self) -> bool {
match self {
Scalar::Rational{v} => v.is_one(),
Scalar::Float{v} => v.is_one(),
}
}
pub fn is_negative(&self) -> bool { pub fn is_negative(&self) -> bool {
match self { match self {
Scalar::Rational{v} => v.is_negative(), Scalar::Rational{v} => v.is_negative(),

View File

@ -110,6 +110,7 @@ impl ScalarBase for RationalBase {
} }
fn is_zero(&self) -> bool {self.val == Rational::from((0,1))} fn is_zero(&self) -> bool {self.val == Rational::from((0,1))}
fn is_one(&self) -> bool {self.val == Rational::from((1,1))}
fn is_negative(&self) -> bool { self.val.clone().signum() == -1 } fn is_negative(&self) -> bool { self.val.clone().signum() == -1 }
fn is_positive(&self) -> bool { self.val.clone().signum() == 1 } fn is_positive(&self) -> bool { self.val.clone().signum() == 1 }

View File

@ -161,9 +161,34 @@ impl Operator {
let (b, div) = (b, div); let (b, div) = (b, div);
if div { if div {
return format!("{} ÷ {}", self.add_parens_to_arg_strict(a), self.add_parens_to_arg_strict(b)); return format!("{} ÷ {}",
self.add_parens_to_arg_strict(a),
self.add_parens_to_arg_strict(b)
);
} else { } else {
return format!("{} × {}", self.add_parens_to_arg_strict(a), self.add_parens_to_arg_strict(b));
// Ommit times sign when we have a number
// multiplied by a unit (like 10 m)
// Times sign should stay in all other cases.
let no_times = if let Token::Number(p) = b {
if let Token::Number(q) = a {
(!p.unitless() && p.is_one()) &&
!(!q.unitless() && p.is_one())
} else {false}
} else {false};
if no_times {
return format!("{} {}",
self.add_parens_to_arg_strict(a),
self.add_parens_to_arg_strict(b)
);
} else {
return format!("{} × {}",
self.add_parens_to_arg_strict(a),
self.add_parens_to_arg_strict(b)
);
}
} }
}, },