diff --git a/kalk/src/interpreter.rs b/kalk/src/interpreter.rs index 4e28d8a..25f4ddd 100644 --- a/kalk/src/interpreter.rs +++ b/kalk/src/interpreter.rs @@ -175,8 +175,8 @@ fn eval_unary_expr( let num = eval_expr(context, &expr, unit)?; match op { - TokenKind::Minus => Ok(KalkNum::new(-num.value, &num.unit)), - TokenKind::Percent => Ok(KalkNum::new(num.value * 0.01, unit)), + TokenKind::Minus => Ok(num.mul(context, KalkNum::from(-1f64))), + TokenKind::Percent => Ok(num.mul(context, KalkNum::from(0.01f64))), TokenKind::Exclamation => Ok(KalkNum::new( prelude::special_funcs::factorial(num.value), unit, diff --git a/kalk/src/kalk_num/mod.rs b/kalk/src/kalk_num/mod.rs index a949e30..75e59b0 100644 --- a/kalk/src/kalk_num/mod.rs +++ b/kalk/src/kalk_num/mod.rs @@ -22,9 +22,7 @@ lazy_static! { let mut m = HashMap::new(); m.insert("3.141592", "π"); m.insert("2.718281", "e"); - m.insert("6.283185", "tau"); m.insert("6.283185", "τ"); - m.insert("1.618033", "phi"); m.insert("1.618033", "ϕ"); m.insert("1.414213", "√2"); // Radian values for common angles @@ -127,11 +125,32 @@ impl KalkNum { } } + pub fn to_string(&self) -> String { + let as_str = trim_number_string(&self.to_f64().to_string()); + + if self.imaginary_value != 0f64 { + let imaginary_as_str = trim_number_string(&self.imaginary_to_f64().to_string()); + let sign = if self.imaginary_value < 0f64 { + "-" + } else { + "+" + }; + + format!("{} {} {}i", as_str, sign, imaginary_as_str) + } else { + as_str + } + } + pub fn to_string_big(&self) -> String { - if self.imaginary_value == 0 { + if self.imaginary_value == 0f64 { self.value.to_string() } else { - let sign = if self.imaginary_value < 0 { "-" } else { "+" }; + let sign = if self.imaginary_value < 0f64 { + "-" + } else { + "+" + }; format!( "{} {} {}", self.value.to_string(), @@ -141,6 +160,23 @@ impl KalkNum { } } + pub fn to_string_real(&self) -> String { + trim_number_string(&self.to_f64().to_string()) + } + + pub fn to_string_imaginary(&self, include_i: bool) -> String { + let value = trim_number_string(&self.imaginary_to_f64().to_string()); + if include_i && value == "1" { + String::from("i") + } else if include_i && value == "-1" { + String::from("-i") + } else if include_i { + format!("{}i", value) + } else { + value + } + } + pub fn to_string_pretty(&self) -> String { let sci_notation_real = self.to_scientific_notation(ComplexNumberType::Real); let result_str = if (-6..8).contains(&sci_notation_real.exponent) || self.value == 0f64 { @@ -156,7 +192,7 @@ impl KalkNum { { self.to_string_imaginary(true) } else { - format!("{} i", sci_notation_imaginary.to_string()) + format!("{}", sci_notation_imaginary.to_string()) }; let mut output = result_str; @@ -166,13 +202,21 @@ impl KalkNum { if output == "0" { output = String::new(); } + + // If there is a real value as well if output.len() > 0 { output.push_str(&format!( - " {} ", - if self.imaginary_value < 0 { "-" } else { "+" } + " {} {}", + if self.imaginary_value < 0f64 { + "-" + } else { + "+" + }, + result_str_imaginary.trim_start_matches("-"), )); + } else { + output.push_str(&format!("{}", result_str_imaginary)); } - output.push_str(&format!("{}", result_str_imaginary)); } let unit = self.get_unit(); @@ -238,8 +282,10 @@ impl KalkNum { pub(crate) fn mul(self, context: &mut crate::interpreter::Context, rhs: KalkNum) -> KalkNum { let right = calculate_unit(context, &self, rhs.clone()).unwrap_or(rhs); + // (a + bi)(c + di) = ac + adi + bci + bdi² KalkNum::new_with_imaginary( - KalkNum::default().value, + self.value.clone() * right.value.clone() + - self.imaginary_value.clone() * right.imaginary_value.clone(), &right.unit, self.value * right.imaginary_value + self.imaginary_value * right.value, ) @@ -349,6 +395,17 @@ impl KalkNum { } } +fn trim_number_string(input: &str) -> String { + if input.contains(".") { + input + .trim_end_matches('0') + .trim_end_matches('.') + .to_string() + } else { + input.into() + } +} + fn calculate_unit( context: &mut crate::interpreter::Context, left: &KalkNum, diff --git a/kalk/src/kalk_num/regular.rs b/kalk/src/kalk_num/regular.rs index fcabaaa..3cb803a 100644 --- a/kalk/src/kalk_num/regular.rs +++ b/kalk/src/kalk_num/regular.rs @@ -32,21 +32,18 @@ impl KalkNum { self.value } + #[wasm_bindgen(js_name = getImaginaryValue)] + pub fn imaginary_to_f64(&self) -> f64 { + self.imaginary_value + } + pub fn to_i32(&self) -> i32 { self.value as i32 } #[wasm_bindgen(js_name = toString)] - pub fn to_string(&self) -> String { - let string_value = self.value.to_string(); - if string_value.contains(".") { - string_value - .trim_end_matches('0') - .trim_end_matches('.') - .to_string() - } else { - string_value - } + pub fn to_string_js(&self) -> String { + self.to_string() } #[wasm_bindgen(js_name = toStringBig)] @@ -75,8 +72,11 @@ impl KalkNum { } #[wasm_bindgen(js_name = toScientificNotation)] - pub fn to_scientific_notation_js(&self) -> ScientificNotation { - self.to_scientific_notation() + pub fn to_scientific_notation_js( + &self, + complex_number_type: ComplexNumberType, + ) -> ScientificNotation { + self.to_scientific_notation(complex_number_type) } #[wasm_bindgen(js_name = estimate)] diff --git a/kalk/src/kalk_num/with_rug.rs b/kalk/src/kalk_num/with_rug.rs index 8fbc307..7505b36 100644 --- a/kalk/src/kalk_num/with_rug.rs +++ b/kalk/src/kalk_num/with_rug.rs @@ -43,34 +43,6 @@ impl KalkNum { self.value.to_i32_saturating().unwrap() } - pub fn to_string(&self) -> String { - let as_str = trim_number_string(&self.to_f64().to_string()); - - if self.imaginary_value != 0 { - let imaginary_as_str = trim_number_string(&self.imaginary_to_f64().to_string()); - let sign = if self.imaginary_value < 0 { "-" } else { "+" }; - - format!("{} {} {}i", as_str, sign, imaginary_as_str) - } else { - as_str - } - } - - pub fn to_string_real(&self) -> String { - trim_number_string(&self.to_f64().to_string()) - } - - pub fn to_string_imaginary(&self, include_i: bool) -> String { - let value = trim_number_string(&self.imaginary_to_f64().to_string()); - if include_i && value == "1" { - String::from("i") - } else if include_i { - format!("{}i", value) - } else { - value - } - } - pub fn get_unit(&self) -> &str { &self.unit } @@ -81,17 +53,6 @@ impl KalkNum { } } -fn trim_number_string(input: &str) -> String { - if input.contains(".") { - input - .trim_end_matches('0') - .trim_end_matches('.') - .to_string() - } else { - input.into() - } -} - impl From for KalkNum { fn from(x: f64) -> Self { KalkNum::new(Float::with_val(63, x), "") diff --git a/kalk_cli/src/main.rs b/kalk_cli/src/main.rs index b60c719..073f95d 100644 --- a/kalk_cli/src/main.rs +++ b/kalk_cli/src/main.rs @@ -7,8 +7,6 @@ use std::env; use std::fs::File; use std::io::Read; -static DEFAULT_PRECISION: u32 = 53; - fn main() { let args: Vec = env::args().collect(); let app = App::new("kalk") diff --git a/kalk_cli/src/output.rs b/kalk_cli/src/output.rs index 6dc7cb7..e05330c 100644 --- a/kalk_cli/src/output.rs +++ b/kalk_cli/src/output.rs @@ -1,4 +1,3 @@ -use crate::DEFAULT_PRECISION; use ansi_term::Colour::Red; use kalk::parser;