1pub trait ToFixedString {
2 fn to_fixed_string(&self, places: isize) -> String;
3}
4
5impl ToFixedString for f64 {
6 fn to_fixed_string(&self, places: isize) -> String {
7 let align_left = places > 0;
8 let places = places.abs().max(6) as usize;
9 let sign = if self.is_sign_negative() { "-" } else { "" };
10 let value = self.abs();
11
12 let (mut mantissa, exp) = if *self == 0.0 {
13 ("0.0".to_string(), "".to_string())
14 } else {
15 let exp = self.abs().log10().floor() as i32 / 3 * 3;
16 if exp > 3 || exp < -3 || value < 0.001 {
17 (format!("{:.6}", value / 10f64.powi(exp)), format!("{:+}", exp))
18 } else {
19 (format!("{:.6}", value), "".to_string())
20 }
21 };
22
23 let mantissa_places = places.saturating_sub(sign.len() + exp.len());
24 if let Some(pos) = mantissa.find('.') {
25 if mantissa_places == pos {
26 mantissa.truncate(pos);
27 } else if mantissa_places > pos {
28 mantissa.truncate(mantissa_places);
29 mantissa = mantissa.trim_end_matches('0').trim_end_matches('.').to_string();
30 }
31 }
32
33 if align_left {
34 format!("{}{}{}{}", sign, mantissa, exp, " ".repeat(mantissa_places.saturating_sub(mantissa.len())))
35 } else {
36 format!("{}{}{}{}", " ".repeat(mantissa_places.saturating_sub(mantissa.len())), sign, mantissa, exp)
37 }
38 }
39}
40
41pub fn to_fixed_string(value: f64, places: isize) -> String {
42 value.to_fixed_string(places)
43}