From 8a026fc2eaf99bb45f355723cd529b2c2941956a Mon Sep 17 00:00:00 2001 From: Mark Date: Wed, 20 Sep 2023 11:07:47 -0700 Subject: [PATCH] Updated scalar print routine --- src/quantity/scalar/f64base.rs | 28 ++++++++++++++++++++- src/quantity/scalar/floatbase.rs | 30 ++++++++++++++++++++++- src/quantity/scalar/mod.rs | 42 ++++++++++---------------------- 3 files changed, 69 insertions(+), 31 deletions(-) diff --git a/src/quantity/scalar/f64base.rs b/src/quantity/scalar/f64base.rs index 5e9bcaf..f9f445e 100644 --- a/src/quantity/scalar/f64base.rs +++ b/src/quantity/scalar/f64base.rs @@ -27,7 +27,33 @@ pub struct F64Base where { impl ToString for F64Base { fn to_string(&self) -> String { - return dec_to_sci(self.val.to_string()); + // Remove negative sign from string + let mut s = self.val.to_string(); + + let neg = s.starts_with("-"); + if neg { s = String::from(&s[1..]); } + + // Power of ten + let mut p: i64 = { + if let Some(x) = s.find(".") { + x as i64 + } else { + s.len() as i64 + } + }; + p -= 1; + + // We no longer need a decimal point in our string. + // also, trim off leading zeros and adjust power. + let mut s: &str = &s.replace(".", ""); + s = &s[0..]; + s = s.trim_end_matches('0'); + while s.starts_with('0') { + s = &s[1..]; + p -= 1; + } + + return dec_to_sci(neg, s.to_string(), p); } } diff --git a/src/quantity/scalar/floatbase.rs b/src/quantity/scalar/floatbase.rs index 77ce0d4..94ff120 100644 --- a/src/quantity/scalar/floatbase.rs +++ b/src/quantity/scalar/floatbase.rs @@ -34,7 +34,35 @@ impl FloatBase { impl ToString for FloatBase { fn to_string(&self) -> String { - return dec_to_sci(self.val.to_string()); + + if self.val.is_nan() { + return "NaN".to_string(); + } else if self.val.is_inf_neg() { + return "-Inf".to_string(); + } else if self.val.is_inf_pos() { + return "+Inf".to_string(); + } + + + // Already in scientific notation,we just need to trim significant digits. + let mut _a = self.val.round(32, astro_float::RoundingMode::Up).to_string(); + let mut _b = _a.split('e'); + + let mut s = String::from(_b.next().unwrap()); // Decimal + let p: i64 = _b.next().unwrap().parse().unwrap(); // Exponent + + // Remove negative sign from string + let neg = s.starts_with("-"); + if neg { s = String::from(&s[1..]); } + + // We no longer need a decimal point in our string. + // also, trim off leading zeros and adjust power. + let mut s: &str = &s.replace(".", ""); + s = &s[0..]; + s = s.trim_end_matches('0'); + s = s.trim_start_matches('0'); + + return dec_to_sci(neg, s.to_string(), p); } } diff --git a/src/quantity/scalar/mod.rs b/src/quantity/scalar/mod.rs index 1b4833c..976998d 100644 --- a/src/quantity/scalar/mod.rs +++ b/src/quantity/scalar/mod.rs @@ -25,36 +25,17 @@ pub use self::scalar::ScalarBase; // Convert a string to scientific notation, // with parameters SHOW_SIG and MAX_LEN. // -// input (s): a decimal of any length, like 123123.123123 -// s may start with an optional `-` sign. -pub(in self) fn dec_to_sci(mut s: String) -> String { - // Remove negative sign from string - let neg = s.starts_with("-"); - if neg { s = String::from(&s[1..]); } - - // Power of ten - let mut p: i32 = { - if let Some(x) = s.find(".") { - x as i32 - } else { - s.len() as i32 - } - }; - p -= 1; - - // We no longer need a decimal point in our string. - // also, trim off leading zeros and adjust power. - let mut s: &str = &s.replace(".", ""); - s = &s[0..]; - s = s.trim_end_matches('0'); - while s.starts_with('0') { - s = &s[1..]; - p -= 1; - } - +// input: +// neg: true if negative +// s: decimal portion. Must contain only digits and a single decimal point. +// zeros must be stripped from both ends. +// p: power of ten to multiply by. +// +// So, (-1)^(neg) + (s * 10^p) should give us our number. +#[allow(dead_code)] +pub(in self) fn dec_to_sci(neg: bool, mut s: String, p: i64) -> String { // Pick significant digits and round - let mut s = String::from(s); if s.len() > SHOW_SIG { let round; if s.len() != SHOW_SIG + 1 { @@ -77,6 +58,8 @@ pub(in self) fn dec_to_sci(mut s: String) -> String { let neg = if neg {"-"} else {""}; if (p.abs() as usize) < MAX_LEN { + // Print whole decimal + if p >= 0 { let q = p as usize; @@ -94,8 +77,9 @@ pub(in self) fn dec_to_sci(mut s: String) -> String { return format!("{neg}{}", t.trim_end_matches('0')); } - // Print full scientific notation } else { + // Print full scientific notation + let first = &s[0..1]; let mut rest = &s[1..]; rest = rest.trim_end_matches('0');