Fixed unit powers

pull/2/head
Mark 2023-04-11 09:05:37 -07:00
parent 0ca7705122
commit 0497cd810d
Signed by: Mark
GPG Key ID: AD62BB059C2AAEE4
2 changed files with 25 additions and 27 deletions

View File

@ -10,7 +10,6 @@ use std::cmp::Ordering;
use crate::quantity::Unit; use crate::quantity::Unit;
use crate::quantity::BaseUnit; use crate::quantity::BaseUnit;
use crate::quantity::Scalar; use crate::quantity::Scalar;
#[derive(Debug)] #[derive(Debug)]
@ -83,7 +82,7 @@ impl Quantity {
}); });
} }
pub fn insert_unit(&mut self, ui: BaseUnit, pi: f64) { self.u.insert(ui, pi) } pub fn insert_unit(&mut self, ui: BaseUnit, pi: Scalar) { self.u.insert(ui, pi) }
pub fn set_unit(&mut self, u: Unit) { self.u = u; } pub fn set_unit(&mut self, u: Unit) { self.u = u; }
pub fn from_unit_string(s: &str) -> Option<Quantity> { pub fn from_unit_string(s: &str) -> Option<Quantity> {
@ -102,7 +101,7 @@ impl Quantity {
if b.is_some() { if b.is_some() {
let mut u = Unit::new(); let mut u = Unit::new();
u.insert(b.unwrap(), 1f64); u.insert(b.unwrap(), Scalar::new_rational(1f64).unwrap());
let mut q = Quantity::new_rational(1f64).unwrap(); let mut q = Quantity::new_rational(1f64).unwrap();
q.set_unit(u); q.set_unit(u);
@ -170,8 +169,8 @@ impl Quantity {
pub fn pow(&self, pwr: Quantity) -> Quantity { pub fn pow(&self, pwr: Quantity) -> Quantity {
Quantity { Quantity {
v: self.v.pow(pwr.v), v: self.v.pow(pwr.v.clone()),
u: self.u.pow(2f64) u: self.u.pow(pwr.v)
} }
} }
} }

View File

@ -4,8 +4,7 @@ use std::ops::{
MulAssign, DivAssign MulAssign, DivAssign
}; };
use crate::quantity::Scalar; use super::Scalar;
use super::Quantity; use super::Quantity;
#[derive(Debug)] #[derive(Debug)]
@ -44,7 +43,7 @@ impl BaseUnit {
match self { match self {
BaseUnit::Foot => Some(Quantity { BaseUnit::Foot => Some(Quantity {
v: Scalar::new_float_from_string("0.3048").unwrap(), v: Scalar::new_float_from_string("0.3048").unwrap(),
u: Unit::from_array(&[(BaseUnit::Meter, 1f64)]) u: Unit::from_array(&[(BaseUnit::Meter, Scalar::new_rational(1f64).unwrap())])
}), }),
_ => None _ => None
} }
@ -56,7 +55,7 @@ impl BaseUnit {
#[derive(Clone)] #[derive(Clone)]
pub struct Unit { pub struct Unit {
// Unit, power. // Unit, power.
pub val: HashMap<BaseUnit, f64> pub val: HashMap<BaseUnit, Scalar>
} }
@ -68,7 +67,7 @@ impl ToString for Unit {
let mut bottom_empty = true; let mut bottom_empty = true;
for (_, p) in &self.val { for (_, p) in &self.val {
if *p > 0f64 { if p.is_positive() {
top_empty = false; top_empty = false;
} else { } else {
bottom_empty = false; bottom_empty = false;
@ -91,21 +90,21 @@ impl ToString for Unit {
BaseUnit::Foot => "ft", BaseUnit::Foot => "ft",
}; };
if *p == 1f64 { if *p == Scalar::new_rational(1f64).unwrap() {
t.push_str(&format!("{c}·")); t.push_str(&format!("{c}·"));
} else if *p == -1f64 { } else if *p == Scalar::new_rational(-1f64).unwrap() {
if top_empty { if top_empty {
b.push_str(&format!("{c}⁻¹·")); b.push_str(&format!("{c}⁻¹·"));
} else { } else {
b.push_str(&format!("{c}·")); b.push_str(&format!("{c}·"));
} }
} else if *p > 0f64 { } else if p.is_positive() {
t.push_str(&format!("{c}^{p}·")); t.push_str(&format!("{c}^{}·", p.to_string()));
} else { } else {
if top_empty { if top_empty {
b.push_str(&format!("{c}^{}·", p)); b.push_str(&format!("{c}^{}·", p.to_string()));
} else { } else {
b.push_str(&format!("{c}^{}·", -p)); b.push_str(&format!("{c}^{}·", (-p.clone()).to_string()));
} }
} }
}; };
@ -129,22 +128,22 @@ impl Unit {
} }
} }
pub fn from_array(a: &[(BaseUnit, f64)]) -> Unit { pub fn from_array(a: &[(BaseUnit, Scalar)]) -> Unit {
let mut n = Unit::new(); let mut n = Unit::new();
for (u, p) in a.iter() { for (u, p) in a.iter() {
n.insert(*u, *p); n.insert(*u, p.clone());
} }
return n; return n;
} }
pub fn unitless(&self) -> bool { self.val.len() == 0 } pub fn unitless(&self) -> bool { self.val.len() == 0 }
pub fn insert(&mut self, u: BaseUnit, p: f64) { pub fn insert(&mut self, u: BaseUnit, p: Scalar) {
match self.val.get_mut(&u) { match self.val.get_mut(&u) {
Some(i) => { Some(i) => {
let n = *i + p; let n = i.clone() + p;
if n == 0f64 { if n.is_zero() {
self.val.remove(&u); self.val.remove(&u);
} else { *i = n; } } else { *i = n; }
}, },
@ -152,10 +151,10 @@ impl Unit {
}; };
} }
pub fn pow(&self, pwr: f64) -> Unit { pub fn pow(&self, pwr: Scalar) -> Unit {
let mut u = self.clone(); let mut u = self.clone();
for (_, p) in &mut u.val { for (_, p) in &mut u.val {
*p *= pwr; *p *= pwr.clone();
}; };
return u; return u;
} }
@ -179,14 +178,14 @@ impl Mul for Unit {
fn mul(self, other: Self) -> Self::Output { fn mul(self, other: Self) -> Self::Output {
let mut o = self.clone(); let mut o = self.clone();
for (u, p) in &other.val { o.insert(*u, *p); } for (u, p) in &other.val { o.insert(*u, p.clone()); }
return o; return o;
} }
} }
impl MulAssign for Unit where { impl MulAssign for Unit where {
fn mul_assign(&mut self, other: Self) { fn mul_assign(&mut self, other: Self) {
for (u, p) in &other.val { self.insert(*u, *p); } for (u, p) in &other.val { self.insert(*u, p.clone()); }
} }
} }
@ -195,13 +194,13 @@ impl Div for Unit {
fn div(self, other: Self) -> Self::Output { fn div(self, other: Self) -> Self::Output {
let mut o = self.clone(); let mut o = self.clone();
for (u, p) in &other.val { o.insert(*u, -*p); } for (u, p) in &other.val { o.insert(*u, -p.clone()); }
return o; return o;
} }
} }
impl DivAssign for Unit where { impl DivAssign for Unit where {
fn div_assign(&mut self, other: Self) { fn div_assign(&mut self, other: Self) {
for (u, p) in &other.val { self.insert(*u, -*p); } for (u, p) in &other.val { self.insert(*u, -p.clone()); }
} }
} }