@@ -101,5 +101,70 @@ pub(crate) fn decimal_to_str(value: Decimal) -> String {
101
101
}
102
102
103
103
pub ( crate ) fn big_decimal_to_str ( value : BigDecimal ) -> String {
104
- value. round ( 12 ) . normalized ( ) . to_string ( )
104
+ // Round the value to limit the number of decimal places
105
+ let value = value. round ( 12 ) . normalized ( ) ;
106
+ // Format the value to a string
107
+ format_big_decimal ( value)
108
+ }
109
+
110
+ fn format_big_decimal ( value : BigDecimal ) -> String {
111
+ let ( integer, scale) = value. into_bigint_and_exponent ( ) ;
112
+ let mut str = integer. to_str_radix ( 10 ) ;
113
+ if scale <= 0 {
114
+ // Append zeros to the right of the integer part
115
+ str. extend ( std:: iter:: repeat ( '0' ) . take ( scale. unsigned_abs ( ) as usize ) ) ;
116
+ str
117
+ } else {
118
+ let ( sign, unsigned_len, unsigned_str) = if integer. is_negative ( ) {
119
+ ( "-" , str. len ( ) - 1 , & str[ 1 ..] )
120
+ } else {
121
+ ( "" , str. len ( ) , & str[ ..] )
122
+ } ;
123
+ let scale = scale as usize ;
124
+ if unsigned_len <= scale {
125
+ format ! ( "{}0.{:0>scale$}" , sign, unsigned_str)
126
+ } else {
127
+ str. insert ( str. len ( ) - scale, '.' ) ;
128
+ str
129
+ }
130
+ }
131
+ }
132
+
133
+ #[ cfg( test) ]
134
+ mod tests {
135
+ use super :: big_decimal_to_str;
136
+ use bigdecimal:: { num_bigint:: BigInt , BigDecimal } ;
137
+
138
+ macro_rules! assert_decimal_str_eq {
139
+ ( $integer: expr, $scale: expr, $expected: expr) => {
140
+ assert_eq!(
141
+ big_decimal_to_str( BigDecimal :: from_bigint(
142
+ BigInt :: from( $integer) ,
143
+ $scale
144
+ ) ) ,
145
+ $expected
146
+ ) ;
147
+ } ;
148
+ }
149
+
150
+ #[ test]
151
+ fn test_big_decimal_to_str ( ) {
152
+ assert_decimal_str_eq ! ( 11 , 3 , "0.011" ) ;
153
+ assert_decimal_str_eq ! ( 11 , 2 , "0.11" ) ;
154
+ assert_decimal_str_eq ! ( 11 , 1 , "1.1" ) ;
155
+ assert_decimal_str_eq ! ( 11 , 0 , "11" ) ;
156
+ assert_decimal_str_eq ! ( 11 , -1 , "110" ) ;
157
+ assert_decimal_str_eq ! ( 0 , 0 , "0" ) ;
158
+
159
+ // Negative cases
160
+ assert_decimal_str_eq ! ( -11 , 3 , "-0.011" ) ;
161
+ assert_decimal_str_eq ! ( -11 , 2 , "-0.11" ) ;
162
+ assert_decimal_str_eq ! ( -11 , 1 , "-1.1" ) ;
163
+ assert_decimal_str_eq ! ( -11 , 0 , "-11" ) ;
164
+ assert_decimal_str_eq ! ( -11 , -1 , "-110" ) ;
165
+
166
+ // Round to 12 decimal places
167
+ // 1.0000000000011 -> 1.000000000001
168
+ assert_decimal_str_eq ! ( 10_i128 . pow( 13 ) + 11 , 13 , "1.000000000001" ) ;
169
+ }
105
170
}
0 commit comments