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