@@ -13,32 +13,91 @@ fn find_minimal_repr(n: f64, eps: f64) -> (f64, usize) {
1313 }
1414}
1515
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 ( ) ;
1920
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 ;
2223
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+ }
2627
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) ;
2930
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+ }
3334
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+ }
3840 }
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 ;
3955 }
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) ;
4078
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+ }
42101}
43102
44103/// The function that pretty prints the floating number
@@ -50,35 +109,12 @@ fn float_to_string(n: f64, max_precision: usize) -> String {
50109/// - `allow_sn`: Should we use scientific notation when possible
51110/// - **returns**: The pretty printed string
52111pub 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)
82118}
83119
84120#[ cfg( test) ]
0 commit comments