diff options
Diffstat (limited to 'src/eval.rs')
| -rw-r--r-- | src/eval.rs | 139 |
1 files changed, 66 insertions, 73 deletions
diff --git a/src/eval.rs b/src/eval.rs index dce9d68..a72f271 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -1,4 +1,5 @@ use std::fmt::{Display, Formatter}; +use Num::{Float, Int}; #[derive(Clone, Copy, Debug, PartialEq)] pub enum Num { @@ -6,25 +7,17 @@ pub enum Num { Float(f64), } -pub fn int(i: i128) -> Num { - Num::Int(i) -} - -pub fn float(f: f64) -> Num { - Num::Float(f) -} - impl Num { fn as_float(self) -> f64 { match self { - Num::Int(i) => i as f64, - Num::Float(f) => f, + Int(i) => i as f64, + Float(f) => f, } } fn powi(self, p: i128) -> Num { if p == 0 { - return int(1); + return Int(1); } if p == 1 { return self; @@ -37,106 +30,106 @@ impl Num { pub fn pow(self, other: Num) -> Num { match other { - Num::Int(i) => { + Int(i) => { if i >= 0 { return self.powi(i); } if let Ok(i_32) = i32::try_from(i) { - return float(self.as_float().powi(i_32)); + return Float(self.as_float().powi(i_32)); } - float(1.).div(self).powi(-i) + Float(1.).div(self).powi(-i) } - Num::Float(f) => float(self.as_float().powf(f)), + Float(f) => Float(self.as_float().powf(f)), } } pub fn mul(self, other: Num) -> Num { - if let (Num::Int(i1), Num::Int(i2)) = (self, other) { + if let (Int(i1), Int(i2)) = (self, other) { if let Some(p) = i1.checked_mul(i2) { - return int(p); + return Int(p); } } - float(self.as_float() * other.as_float()) + Float(self.as_float() * other.as_float()) } pub fn div(self, other: Num) -> Num { - float(self.as_float() / other.as_float()) + Float(self.as_float() / other.as_float()) } pub fn int_div(self, other: Num) -> Num { - if let (Num::Int(i1), Num::Int(i2)) = (self, other) { + if let (Int(i1), Int(i2)) = (self, other) { if let Some(q) = i1.checked_div(i2) { - return int(q); + return Int(q); } } - int((self.as_float() / other.as_float()) as i128) + Int((self.as_float() / other.as_float()) as i128) } pub fn modulo(self, other: Num) -> Num { - if let (Num::Int(i1), Num::Int(i2)) = (self, other) { + if let (Int(i1), Int(i2)) = (self, other) { if let Some(r) = i1.checked_rem(i2) { if i2 > 0 && r < 0 || i2 < 0 && r > 0 { - return int(r + i2); + return Int(r + i2); } - return int(r); + return Int(r); } } let n1 = self.as_float(); let n2 = other.as_float(); let r = n1 % n2; if n2 > 0. && r < 0. || n2 < 0. && r > 0. { - return float(r + n2); + return Float(r + n2); } - float(r) + Float(r) } pub fn add(self, other: Num) -> Num { - if let (Num::Int(i1), Num::Int(i2)) = (self, other) { + if let (Int(i1), Int(i2)) = (self, other) { if let Some(s) = i1.checked_add(i2) { - return int(s); + return Int(s); } } - float(self.as_float() + other.as_float()) + Float(self.as_float() + other.as_float()) } pub fn sub(self, other: Num) -> Num { - if let (Num::Int(i1), Num::Int(i2)) = (self, other) { + if let (Int(i1), Int(i2)) = (self, other) { if let Some(d) = i1.checked_sub(i2) { - return int(d); + return Int(d); } } - float(self.as_float() - other.as_float()) + Float(self.as_float() - other.as_float()) } pub fn sin(self) -> Num { - float(self.as_float().sin()) + Float(self.as_float().sin()) } pub fn cos(self) -> Num { - float(self.as_float().cos()) + Float(self.as_float().cos()) } pub fn tan(self) -> Num { - float(self.as_float().tan()) + Float(self.as_float().tan()) } pub fn asin(self) -> Num { - float(self.as_float().asin()) + Float(self.as_float().asin()) } pub fn acos(self) -> Num { - float(self.as_float().acos()) + Float(self.as_float().acos()) } pub fn atan(self) -> Num { - float(self.as_float().atan()) + Float(self.as_float().atan()) } pub fn sqrt(self) -> Num { match self { - Num::Int(i) if i >= 0 => { + Int(i) if i >= 0 => { if i <= 1 { - return int(i); + return Int(i); } let mut x0 = i / 2; let mut x1 = (x0 + i / x0) / 2; @@ -145,51 +138,51 @@ impl Num { x1 = (x0 + i / x0) / 2; } if x0 * x0 == i { - return int(x0); + return Int(x0); } } _ => (), } - float(self.as_float().sqrt()) + Float(self.as_float().sqrt()) } pub fn log(self) -> Num { - float(self.as_float().ln()) + Float(self.as_float().ln()) } pub fn log10(self) -> Num { - float(self.as_float().log10()) + Float(self.as_float().log10()) } pub fn log2(self) -> Num { - float(self.as_float().log2()) + Float(self.as_float().log2()) } pub fn floor(self) -> Num { match self { - Num::Int(i) => int(i), - Num::Float(f) => int(f.floor() as i128), + Int(i) => Int(i), + Float(f) => Int(f.floor() as i128), } } pub fn ceil(self) -> Num { match self { - Num::Int(i) => int(i), - Num::Float(f) => int(f.ceil() as i128), + Int(i) => Int(i), + Float(f) => Int(f.ceil() as i128), } } pub fn round(self) -> Num { match self { - Num::Int(i) => int(i), - Num::Float(f) => int(f.round_ties_even() as i128), + Int(i) => Int(i), + Float(f) => Int(f.round_ties_even() as i128), } } pub fn abs(self) -> Num { match self { - Num::Int(i) => int(i.abs()), - Num::Float(f) => float(f.abs()), + Int(i) => Int(i.abs()), + Float(f) => Float(f.abs()), } } } @@ -197,8 +190,8 @@ impl Num { impl Display for Num { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { match self { - Num::Int(n) => write!(f, "{n}"), - Num::Float(n) => { + Int(n) => write!(f, "{n}"), + Float(n) => { if !(-1e30..=1e30).contains(n) { return write!(f, "{n:.7e}"); } @@ -218,76 +211,76 @@ mod tests { #[test] fn pow_positive_int() { - assert_eq!(int(2).pow(int(16)), int(65536)); + assert_eq!(Int(2).pow(Int(16)), Int(65536)); } #[test] fn pow_negative_int() { - assert_eq!(int(2).pow(int(-3)), float(0.125)); + assert_eq!(Int(2).pow(Int(-3)), Float(0.125)); } #[test] fn pow_float() { - assert_eq!(int(4).pow(float(0.5)), float(2.)); + assert_eq!(Int(4).pow(Float(0.5)), Float(2.)); } #[test] fn pow_overflow() { - assert_eq!(int(2).pow(int(1 << 126)), float(f64::INFINITY)); + assert_eq!(Int(2).pow(Int(1 << 126)), Float(f64::INFINITY)); } #[test] fn pow_underflow() { - assert_eq!(int(2).pow(int(-(1 << 126))), float(0.)); + assert_eq!(Int(2).pow(Int(-(1 << 126))), Float(0.)); } #[test] fn modulo_pos() { - assert_eq!(int(5).modulo(int(3)), int(2)); + assert_eq!(Int(5).modulo(Int(3)), Int(2)); } #[test] fn modulo_pos_neg() { - assert_eq!(int(5).modulo(int(-3)), int(-1)); + assert_eq!(Int(5).modulo(Int(-3)), Int(-1)); } #[test] fn modulo_neg_pos() { - assert_eq!(int(-5).modulo(int(3)), int(1)); + assert_eq!(Int(-5).modulo(Int(3)), Int(1)); } #[test] fn modulo_neg() { - assert_eq!(int(-5).modulo(int(-3)), int(-2)); + assert_eq!(Int(-5).modulo(Int(-3)), Int(-2)); } #[test] fn modulo_float_pos() { - assert_eq!(float(5.).modulo(int(3)), float(2.)); + assert_eq!(Float(5.).modulo(Int(3)), Float(2.)); } #[test] fn modulo_float_pos_neg() { - assert_eq!(float(5.).modulo(int(-3)), float(-1.)); + assert_eq!(Float(5.).modulo(Int(-3)), Float(-1.)); } #[test] fn modulo_float_neg_pos() { - assert_eq!(float(-5.).modulo(int(3)), float(1.)); + assert_eq!(Float(-5.).modulo(Int(3)), Float(1.)); } #[test] fn modulo_float_neg() { - assert_eq!(float(-5.).modulo(int(-3)), float(-2.)); + assert_eq!(Float(-5.).modulo(Int(-3)), Float(-2.)); } #[test] fn sqrt() { for n in 0..65536 { assert_eq!( - int(n * n).sqrt(), - int(n), - "int({}).sqrt() is not equal to {}", + Int(n * n).sqrt(), + Int(n), + "Int({}).sqrt() is not equal to {}", n * n, n ); @@ -296,6 +289,6 @@ mod tests { #[test] fn sqrt_big() { - assert_eq!(int(1 << 126).sqrt(), int(1 << 63)); + assert_eq!(Int(1 << 126).sqrt(), Int(1 << 63)); } } |
