exercises

Log | Files | Refs | README

number.rs (1920B)


      1 use crate::NumberToken;
      2 
      3 #[derive(Debug, Clone, PartialEq)]
      4 pub struct Number {
      5     pub value: f64,
      6     pub format: NumberFormat,
      7 }
      8 
      9 impl Number {
     10     pub fn format(&self) -> String {
     11         match self.format {
     12             NumberFormat::Decimal => format!("{}", self.value),
     13             NumberFormat::Scientific => format!("{:e}", self.value),
     14             NumberFormat::Engineering => {
     15                 // Engineering notation adjusts exponent to be multiple of 3
     16                 let exp = self.value.abs().log10().floor();
     17                 let adj_exp = (exp - exp % 3.0).floor();
     18                 let coeff = self.value / 10_f64.powf(adj_exp);
     19                 format!("{}e{}", coeff, adj_exp)
     20             }
     21         }
     22     }
     23 }
     24 
     25 #[derive(Debug, Default, Clone, PartialEq)]
     26 pub enum NumberFormat {
     27     #[default]
     28     Decimal,
     29     Scientific,
     30     Engineering,
     31 }
     32 
     33 #[derive(Debug, Clone, Default)]
     34 pub enum AngleMode {
     35     Degrees,
     36     #[default]
     37     Radians,
     38 }
     39 
     40 #[derive(Clone)]
     41 pub struct StandardNumber(pub f64);
     42 
     43 impl NumberToken for StandardNumber {
     44     fn value(&self) -> f64 {
     45         self.0
     46     }
     47 
     48     fn format(&self) -> String {
     49         format!("{}", self.0)
     50     }
     51 }
     52 
     53 #[derive(Clone)]
     54 pub struct ScientificNumber {
     55     pub value: f64,
     56     pub format: NumberFormat,
     57 }
     58 
     59 /// Different factory families can have different internal representations
     60 impl NumberToken for ScientificNumber {
     61     fn value(&self) -> f64 {
     62         self.value
     63     }
     64 
     65     fn format(&self) -> String {
     66         match self.format {
     67             NumberFormat::Scientific => format!("{:e}", self.value),
     68             NumberFormat::Engineering => {
     69                 let exp = self.value.abs().log10().floor();
     70                 let adj_exp = (exp - exp % 3.0).floor();
     71                 let coeff = self.value / 10_f64.powf(adj_exp);
     72                 format!("{}e{}", coeff, adj_exp)
     73             }
     74             _ => format!("{}", self.value),
     75         }
     76     }
     77 }