@@ -13,32 +13,91 @@ fn find_minimal_repr(n: f64, eps: f64) -> (f64, usize) {
13
13
}
14
14
}
15
15
16
- fn float_to_string ( n : f64 , max_precision : usize ) -> String {
17
- let ( sign, n) = if n < 0.0 { ( "-" , -n) } else { ( "" , n) } ;
18
- let int_part = n. floor ( ) ;
16
+ fn float_to_string ( n : f64 , max_precision : usize , min_decimal : usize ) -> String {
17
+ let ( mut result, mut count) = loop {
18
+ let ( sign, n) = if n < 0.0 { ( "-" , -n) } else { ( "" , n) } ;
19
+ let int_part = n. floor ( ) ;
19
20
20
- let dec_part =
21
- ( ( n. abs ( ) - int_part. abs ( ) ) * ( 10.0f64 ) . powf ( max_precision as f64 ) ) . round ( ) as u64 ;
21
+ let dec_part =
22
+ ( ( n. abs ( ) - int_part. abs ( ) ) * ( 10.0f64 ) . powi ( max_precision as i32 ) ) . round ( ) as u64 ;
22
23
23
- if dec_part == 0 || max_precision == 0 {
24
- return format ! ( "{}{:.0}" , sign, int_part) ;
25
- }
24
+ if dec_part == 0 || max_precision == 0 {
25
+ break ( format ! ( "{}{:.0}" , sign, int_part) , 0 ) ;
26
+ }
26
27
27
- let mut leading = "" . to_string ( ) ;
28
- let mut dec_result = format ! ( "{}" , dec_part) ;
28
+ let mut leading = "" . to_string ( ) ;
29
+ let mut dec_result = format ! ( "{}" , dec_part) ;
29
30
30
- for _ in 0 ..( max_precision - dec_result. len ( ) ) {
31
- leading. push ( '0' ) ;
32
- }
31
+ for _ in 0 ..( max_precision - dec_result. len ( ) ) {
32
+ leading. push ( '0' ) ;
33
+ }
33
34
34
- while let Some ( c) = dec_result. pop ( ) {
35
- if c != '0' {
36
- dec_result. push ( c) ;
37
- break ;
35
+ while let Some ( c) = dec_result. pop ( ) {
36
+ if c != '0' {
37
+ dec_result. push ( c) ;
38
+ break ;
39
+ }
38
40
}
41
+
42
+ break (
43
+ format ! ( "{}{:.0}.{}{}" , sign, int_part, leading, dec_result) ,
44
+ leading. len ( ) + dec_result. len ( ) ,
45
+ ) ;
46
+ } ;
47
+
48
+ if count == 0 && min_decimal > 0 {
49
+ result. push ( '.' ) ;
50
+ }
51
+
52
+ while count < min_decimal {
53
+ result. push ( '0' ) ;
54
+ count += 1 ;
39
55
}
56
+ result
57
+ }
58
+
59
+ pub struct FloatPrettyPrinter {
60
+ pub allow_scientific : bool ,
61
+ pub min_decimal : i32 ,
62
+ pub max_decimal : i32 ,
63
+ }
64
+
65
+ impl FloatPrettyPrinter {
66
+ pub fn print ( & self , n : f64 ) -> String {
67
+ let ( n, p) = find_minimal_repr ( n, ( 10f64 ) . powi ( -self . max_decimal ) ) ;
68
+ let d_repr = float_to_string ( n, p, self . min_decimal as usize ) ;
69
+ if !self . allow_scientific {
70
+ d_repr
71
+ } else {
72
+ if n == 0.0 {
73
+ return "0" . to_string ( ) ;
74
+ }
75
+
76
+ let mut idx = n. abs ( ) . log10 ( ) . floor ( ) ;
77
+ let mut exp = ( 10.0f64 ) . powf ( idx) ;
40
78
41
- format ! ( "{}{:.0}.{}{}" , sign, int_part, leading, dec_result)
79
+ if n. abs ( ) / exp + 1e-5 >= 10.0 {
80
+ idx += 1.0 ;
81
+ exp *= 10.0 ;
82
+ }
83
+
84
+ if idx. abs ( ) < 3.0 {
85
+ return d_repr;
86
+ }
87
+
88
+ let ( sn, sp) = find_minimal_repr ( n / exp, 1e-5 ) ;
89
+ let s_repr = format ! (
90
+ "{}e{}" ,
91
+ float_to_string( sn, sp, self . min_decimal as usize ) ,
92
+ float_to_string( idx, 0 , 0 )
93
+ ) ;
94
+ if s_repr. len ( ) + 1 < d_repr. len ( ) {
95
+ s_repr
96
+ } else {
97
+ d_repr
98
+ }
99
+ }
100
+ }
42
101
}
43
102
44
103
/// The function that pretty prints the floating number
@@ -50,35 +109,12 @@ fn float_to_string(n: f64, max_precision: usize) -> String {
50
109
/// - `allow_sn`: Should we use scientific notation when possible
51
110
/// - **returns**: The pretty printed string
52
111
pub fn pretty_print_float ( n : f64 , allow_sn : bool ) -> String {
53
- let ( n, p) = find_minimal_repr ( n, 1e-10 ) ;
54
- let d_repr = float_to_string ( n, p) ;
55
- if !allow_sn {
56
- d_repr
57
- } else {
58
- if n == 0.0 {
59
- return "0" . to_string ( ) ;
60
- }
61
-
62
- let mut idx = n. abs ( ) . log10 ( ) . floor ( ) ;
63
- let mut exp = ( 10.0f64 ) . powf ( idx) ;
64
-
65
- if n. abs ( ) / exp + 1e-5 >= 10.0 {
66
- idx += 1.0 ;
67
- exp *= 10.0 ;
68
- }
69
-
70
- if idx. abs ( ) < 3.0 {
71
- return d_repr;
72
- }
73
-
74
- let ( sn, sp) = find_minimal_repr ( n / exp, 1e-5 ) ;
75
- let s_repr = format ! ( "{}e{}" , float_to_string( sn, sp) , float_to_string( idx, 0 ) ) ;
76
- if s_repr. len ( ) + 1 < d_repr. len ( ) {
77
- s_repr
78
- } else {
79
- d_repr
80
- }
81
- }
112
+ ( FloatPrettyPrinter {
113
+ allow_scientific : allow_sn,
114
+ min_decimal : 0 ,
115
+ max_decimal : 10 ,
116
+ } )
117
+ . print ( n)
82
118
}
83
119
84
120
#[ cfg( test) ]
0 commit comments