1use alloy::primitives::{I256, U256};
23
24pub fn convert_i256_to_f64(amount: I256, decimals: u8) -> anyhow::Result<f64> {
30 let is_negative = amount.is_negative();
32 let abs_amount = if is_negative { -amount } else { amount };
33
34 let amount_str = abs_amount.to_string();
36 let mut amount_f64: f64 = amount_str
37 .parse()
38 .map_err(|e| anyhow::anyhow!("Failed to parse I256 to f64: {}", e))?;
39
40 if is_negative {
42 amount_f64 = -amount_f64;
43 }
44
45 let factor = 10f64.powi(i32::from(decimals));
47 Ok(amount_f64 / factor)
48}
49
50pub fn convert_u256_to_f64(amount: U256, decimals: u8) -> anyhow::Result<f64> {
56 let amount_str = amount.to_string();
58 let amount_f64: f64 = amount_str
59 .parse()
60 .map_err(|e| anyhow::anyhow!("Failed to parse U256 to f64: {}", e))?;
61
62 let factor = 10f64.powi(i32::from(decimals));
64 Ok(amount_f64 / factor)
65}
66
67#[cfg(test)]
68mod tests {
69 use std::str::FromStr;
70
71 use alloy::primitives::{I256, U256};
72 use rstest::rstest;
73
74 use super::*;
75
76 #[rstest]
77 fn test_convert_positive_i256_to_f64() {
78 let amount = I256::from_str("1000000").unwrap();
80 let result = convert_i256_to_f64(amount, 6).unwrap();
81 assert_eq!(result, 1.0);
82
83 let amount = I256::from_str("1000000000000000000").unwrap();
85 let result = convert_i256_to_f64(amount, 18).unwrap();
86 assert_eq!(result, 1.0);
87 }
88
89 #[rstest]
90 fn test_convert_negative_i256_to_f64() {
91 let amount = I256::from_str("-1000000").unwrap();
93 let result = convert_i256_to_f64(amount, 6).unwrap();
94 assert_eq!(result, -1.0);
95
96 let amount = I256::from_str("-2500000000000000000").unwrap();
98 let result = convert_i256_to_f64(amount, 18).unwrap();
99 assert_eq!(result, -2.5);
100 }
101
102 #[rstest]
103 fn test_convert_zero_i256_to_f64() {
104 let amount = I256::ZERO;
105 let result = convert_i256_to_f64(amount, 6).unwrap();
106 assert_eq!(result, 0.0);
107
108 let result = convert_i256_to_f64(amount, 18).unwrap();
109 assert_eq!(result, 0.0);
110 }
111
112 #[rstest]
113 fn test_convert_fractional_amounts() {
114 let amount = I256::from_str("500000").unwrap();
116 let result = convert_i256_to_f64(amount, 6).unwrap();
117 assert_eq!(result, 0.5);
118
119 let amount = I256::from_str("123456").unwrap();
121 let result = convert_i256_to_f64(amount, 6).unwrap();
122 assert_eq!(result, 0.123456);
123
124 let amount = I256::from_str("-123456").unwrap();
126 let result = convert_i256_to_f64(amount, 6).unwrap();
127 assert_eq!(result, -0.123456);
128 }
129
130 #[rstest]
131 fn test_convert_large_i256_values() {
132 let large_value = U256::from(10).pow(U256::from(30)); let amount = I256::try_from(large_value).unwrap();
135 let result = convert_i256_to_f64(amount, 18).unwrap();
136 assert_eq!(result, 1e12); let amount = I256::from_str("9007199254740991").unwrap(); let result = convert_i256_to_f64(amount, 0).unwrap();
141 assert_eq!(result, 9_007_199_254_740_991.0);
142 }
143
144 #[rstest]
145 fn test_convert_with_different_decimals() {
146 let amount = I256::from_str("1000000000").unwrap();
147
148 let result = convert_i256_to_f64(amount, 0).unwrap();
150 assert_eq!(result, 1_000_000_000.0);
151
152 let result = convert_i256_to_f64(amount, 9).unwrap();
154 assert_eq!(result, 1.0);
155
156 let result = convert_i256_to_f64(amount, 12).unwrap();
158 assert_eq!(result, 0.001);
159 }
160
161 #[rstest]
162 fn test_convert_edge_cases() {
163 let amount = I256::from_str("1").unwrap();
165 let result = convert_i256_to_f64(amount, 18).unwrap();
166 assert_eq!(result, 1e-18);
167
168 let amount = I256::from_str("100").unwrap();
170 let result = convert_i256_to_f64(amount, 6).unwrap();
171 assert_eq!(result, 0.0001);
172 }
173
174 #[rstest]
175 fn test_convert_real_world_examples() {
176 let amount = I256::from_str("1234567890").unwrap();
178 let result = convert_i256_to_f64(amount, 6).unwrap();
179 assert!((result - 1234.567890).abs() < f64::EPSILON);
180
181 let amount = I256::from_str("-5000000000000000").unwrap();
183 let result = convert_i256_to_f64(amount, 18).unwrap();
184 assert_eq!(result, -0.005);
185
186 let amount = I256::from_str("10000000000000").unwrap();
188 let result = convert_i256_to_f64(amount, 8).unwrap();
189 assert_eq!(result, 100_000.0);
190 }
191
192 #[rstest]
193 fn test_precision_boundaries() {
194 let max_safe = I256::from_str("9007199254740992").unwrap(); let result = convert_i256_to_f64(max_safe, 0).unwrap();
198 assert_eq!(result, 9_007_199_254_740_992.0);
199
200 let amount = I256::from_str("1234567890123456789").unwrap();
202 let result = convert_i256_to_f64(amount, 9).unwrap();
203 assert!((result - 1_234_567_890.123_456_7).abs() < 1.0); }
205
206 #[rstest]
208 fn test_convert_positive_u256_to_f64() {
209 let amount = U256::from_str("1000000").unwrap();
211 let result = convert_u256_to_f64(amount, 6).unwrap();
212 assert_eq!(result, 1.0);
213
214 let amount = U256::from_str("1000000000000000000").unwrap();
216 let result = convert_u256_to_f64(amount, 18).unwrap();
217 assert_eq!(result, 1.0);
218 }
219
220 #[rstest]
221 fn test_convert_zero_u256_to_f64() {
222 let amount = U256::ZERO;
223 let result = convert_u256_to_f64(amount, 6).unwrap();
224 assert_eq!(result, 0.0);
225
226 let result = convert_u256_to_f64(amount, 18).unwrap();
227 assert_eq!(result, 0.0);
228 }
229
230 #[rstest]
231 fn test_convert_fractional_u256_amounts() {
232 let amount = U256::from_str("500000").unwrap();
234 let result = convert_u256_to_f64(amount, 6).unwrap();
235 assert_eq!(result, 0.5);
236
237 let amount = U256::from_str("123456").unwrap();
239 let result = convert_u256_to_f64(amount, 6).unwrap();
240 assert_eq!(result, 0.123456);
241 }
242
243 #[rstest]
244 fn test_convert_large_u256_values() {
245 let large_value = U256::from(10).pow(U256::from(30)); let result = convert_u256_to_f64(large_value, 18).unwrap();
248 assert_eq!(result, 1e12); let amount = U256::from_str("9007199254740991").unwrap(); let result = convert_u256_to_f64(amount, 0).unwrap();
253 assert_eq!(result, 9_007_199_254_740_991.0);
254 }
255
256 #[rstest]
257 fn test_convert_u256_with_different_decimals() {
258 let amount = U256::from_str("1000000000").unwrap();
259
260 let result = convert_u256_to_f64(amount, 0).unwrap();
262 assert_eq!(result, 1_000_000_000.0);
263
264 let result = convert_u256_to_f64(amount, 9).unwrap();
266 assert_eq!(result, 1.0);
267
268 let result = convert_u256_to_f64(amount, 12).unwrap();
270 assert_eq!(result, 0.001);
271 }
272
273 #[rstest]
274 fn test_convert_u256_edge_cases() {
275 let amount = U256::from_str("1").unwrap();
277 let result = convert_u256_to_f64(amount, 18).unwrap();
278 assert_eq!(result, 1e-18);
279
280 let amount = U256::from_str("100").unwrap();
282 let result = convert_u256_to_f64(amount, 6).unwrap();
283 assert_eq!(result, 0.0001);
284 }
285
286 #[rstest]
287 fn test_convert_u256_real_world_examples() {
288 let amount = U256::from_str("1234567890").unwrap();
290 let result = convert_u256_to_f64(amount, 6).unwrap();
291 assert!((result - 1234.567890).abs() < f64::EPSILON);
292
293 let amount = U256::from_str("10000000000000").unwrap();
295 let result = convert_u256_to_f64(amount, 8).unwrap();
296 assert_eq!(result, 100_000.0);
297
298 let amount = U256::from_str("1000000000000000000000000000000").unwrap(); let result = convert_u256_to_f64(amount, 18).unwrap();
301 assert_eq!(result, 1e12);
302 }
303
304 #[rstest]
305 fn test_convert_u256_precision_boundaries() {
306 let max_safe = U256::from_str("9007199254740992").unwrap(); let result = convert_u256_to_f64(max_safe, 0).unwrap();
310 assert_eq!(result, 9_007_199_254_740_992.0);
311
312 let amount = U256::from_str("1234567890123456789").unwrap();
314 let result = convert_u256_to_f64(amount, 9).unwrap();
315 assert!((result - 1_234_567_890.123_456_7).abs() < 1.0); }
317
318 #[rstest]
319 fn test_convert_u256_vs_i256_consistency() {
320 let u256_amount = U256::from_str("1000000000000000000").unwrap();
322 let i256_amount = I256::from_str("1000000000000000000").unwrap();
323
324 let u256_result = convert_u256_to_f64(u256_amount, 18).unwrap();
325 let i256_result = convert_i256_to_f64(i256_amount, 18).unwrap();
326
327 assert_eq!(u256_result, i256_result);
328 assert_eq!(u256_result, 1.0);
329 }
330
331 #[rstest]
332 fn test_convert_u256_max_values() {
333 let large_u256 = U256::from(2).pow(U256::from(255)); let result = convert_u256_to_f64(large_u256, 0).unwrap();
336 assert!(result.is_finite());
338 assert!(result > 0.0);
339
340 let large_u256_with_decimals = U256::from(2).pow(U256::from(60)); let result = convert_u256_to_f64(large_u256_with_decimals, 18).unwrap();
343 assert!(result.is_finite());
345 assert!(result > 1.0);
346 assert!(result < 2.0); }
348}