use alloy::primitives::{I256, U256};
pub fn convert_i256_to_f64(amount: I256, decimals: u8) -> anyhow::Result<f64> {
let is_negative = amount.is_negative();
let abs_amount = if is_negative { -amount } else { amount };
let amount_str = abs_amount.to_string();
let mut amount_f64: f64 = amount_str
.parse()
.map_err(|e| anyhow::anyhow!("Failed to parse I256 to f64: {e}"))?;
if is_negative {
amount_f64 = -amount_f64;
}
let factor = 10f64.powi(i32::from(decimals));
Ok(amount_f64 / factor)
}
pub fn convert_u256_to_f64(amount: U256, decimals: u8) -> anyhow::Result<f64> {
let amount_str = amount.to_string();
let amount_f64: f64 = amount_str
.parse()
.map_err(|e| anyhow::anyhow!("Failed to parse U256 to f64: {e}"))?;
let factor = 10f64.powi(i32::from(decimals));
Ok(amount_f64 / factor)
}
#[cfg(test)]
mod tests {
use std::str::FromStr;
use alloy::primitives::{I256, U256};
use rstest::rstest;
use super::*;
#[rstest]
fn test_convert_positive_i256_to_f64() {
let amount = I256::from_str("1000000").unwrap();
let result = convert_i256_to_f64(amount, 6).unwrap();
assert_eq!(result, 1.0);
let amount = I256::from_str("1000000000000000000").unwrap();
let result = convert_i256_to_f64(amount, 18).unwrap();
assert_eq!(result, 1.0);
}
#[rstest]
fn test_convert_negative_i256_to_f64() {
let amount = I256::from_str("-1000000").unwrap();
let result = convert_i256_to_f64(amount, 6).unwrap();
assert_eq!(result, -1.0);
let amount = I256::from_str("-2500000000000000000").unwrap();
let result = convert_i256_to_f64(amount, 18).unwrap();
assert_eq!(result, -2.5);
}
#[rstest]
fn test_convert_zero_i256_to_f64() {
let amount = I256::ZERO;
let result = convert_i256_to_f64(amount, 6).unwrap();
assert_eq!(result, 0.0);
let result = convert_i256_to_f64(amount, 18).unwrap();
assert_eq!(result, 0.0);
}
#[rstest]
fn test_convert_fractional_amounts() {
let amount = I256::from_str("500000").unwrap();
let result = convert_i256_to_f64(amount, 6).unwrap();
assert_eq!(result, 0.5);
let amount = I256::from_str("123456").unwrap();
let result = convert_i256_to_f64(amount, 6).unwrap();
assert_eq!(result, 0.123456);
let amount = I256::from_str("-123456").unwrap();
let result = convert_i256_to_f64(amount, 6).unwrap();
assert_eq!(result, -0.123456);
}
#[rstest]
fn test_convert_large_i256_values() {
let large_value = U256::from(10).pow(U256::from(30)); let amount = I256::try_from(large_value).unwrap();
let result = convert_i256_to_f64(amount, 18).unwrap();
assert_eq!(result, 1e12);
let amount = I256::from_str("9007199254740991").unwrap(); let result = convert_i256_to_f64(amount, 0).unwrap();
assert_eq!(result, 9_007_199_254_740_991.0);
}
#[rstest]
fn test_convert_with_different_decimals() {
let amount = I256::from_str("1000000000").unwrap();
let result = convert_i256_to_f64(amount, 0).unwrap();
assert_eq!(result, 1_000_000_000.0);
let result = convert_i256_to_f64(amount, 9).unwrap();
assert_eq!(result, 1.0);
let result = convert_i256_to_f64(amount, 12).unwrap();
assert_eq!(result, 0.001);
}
#[rstest]
fn test_convert_edge_cases() {
let amount = I256::from_str("1").unwrap();
let result = convert_i256_to_f64(amount, 18).unwrap();
assert_eq!(result, 1e-18);
let amount = I256::from_str("100").unwrap();
let result = convert_i256_to_f64(amount, 6).unwrap();
assert_eq!(result, 0.0001);
}
#[rstest]
fn test_convert_real_world_examples() {
let amount = I256::from_str("1234567890").unwrap();
let result = convert_i256_to_f64(amount, 6).unwrap();
assert!((result - 1234.567890).abs() < f64::EPSILON);
let amount = I256::from_str("-5000000000000000").unwrap();
let result = convert_i256_to_f64(amount, 18).unwrap();
assert_eq!(result, -0.005);
let amount = I256::from_str("10000000000000").unwrap();
let result = convert_i256_to_f64(amount, 8).unwrap();
assert_eq!(result, 100_000.0);
}
#[rstest]
fn test_precision_boundaries() {
let max_safe = I256::from_str("9007199254740992").unwrap(); let result = convert_i256_to_f64(max_safe, 0).unwrap();
assert_eq!(result, 9_007_199_254_740_992.0);
let amount = I256::from_str("1234567890123456789").unwrap();
let result = convert_i256_to_f64(amount, 9).unwrap();
assert!((result - 1_234_567_890.123_456_7).abs() < 1.0); }
#[rstest]
fn test_convert_positive_u256_to_f64() {
let amount = U256::from_str("1000000").unwrap();
let result = convert_u256_to_f64(amount, 6).unwrap();
assert_eq!(result, 1.0);
let amount = U256::from_str("1000000000000000000").unwrap();
let result = convert_u256_to_f64(amount, 18).unwrap();
assert_eq!(result, 1.0);
}
#[rstest]
fn test_convert_zero_u256_to_f64() {
let amount = U256::ZERO;
let result = convert_u256_to_f64(amount, 6).unwrap();
assert_eq!(result, 0.0);
let result = convert_u256_to_f64(amount, 18).unwrap();
assert_eq!(result, 0.0);
}
#[rstest]
fn test_convert_fractional_u256_amounts() {
let amount = U256::from_str("500000").unwrap();
let result = convert_u256_to_f64(amount, 6).unwrap();
assert_eq!(result, 0.5);
let amount = U256::from_str("123456").unwrap();
let result = convert_u256_to_f64(amount, 6).unwrap();
assert_eq!(result, 0.123456);
}
#[rstest]
fn test_convert_large_u256_values() {
let large_value = U256::from(10).pow(U256::from(30)); let result = convert_u256_to_f64(large_value, 18).unwrap();
assert_eq!(result, 1e12);
let amount = U256::from_str("9007199254740991").unwrap(); let result = convert_u256_to_f64(amount, 0).unwrap();
assert_eq!(result, 9_007_199_254_740_991.0);
}
#[rstest]
fn test_convert_u256_with_different_decimals() {
let amount = U256::from_str("1000000000").unwrap();
let result = convert_u256_to_f64(amount, 0).unwrap();
assert_eq!(result, 1_000_000_000.0);
let result = convert_u256_to_f64(amount, 9).unwrap();
assert_eq!(result, 1.0);
let result = convert_u256_to_f64(amount, 12).unwrap();
assert_eq!(result, 0.001);
}
#[rstest]
fn test_convert_u256_edge_cases() {
let amount = U256::from_str("1").unwrap();
let result = convert_u256_to_f64(amount, 18).unwrap();
assert_eq!(result, 1e-18);
let amount = U256::from_str("100").unwrap();
let result = convert_u256_to_f64(amount, 6).unwrap();
assert_eq!(result, 0.0001);
}
#[rstest]
fn test_convert_u256_real_world_examples() {
let amount = U256::from_str("1234567890").unwrap();
let result = convert_u256_to_f64(amount, 6).unwrap();
assert!((result - 1234.567890).abs() < f64::EPSILON);
let amount = U256::from_str("10000000000000").unwrap();
let result = convert_u256_to_f64(amount, 8).unwrap();
assert_eq!(result, 100_000.0);
let amount = U256::from_str("1000000000000000000000000000000").unwrap(); let result = convert_u256_to_f64(amount, 18).unwrap();
assert_eq!(result, 1e12);
}
#[rstest]
fn test_convert_u256_precision_boundaries() {
let max_safe = U256::from_str("9007199254740992").unwrap(); let result = convert_u256_to_f64(max_safe, 0).unwrap();
assert_eq!(result, 9_007_199_254_740_992.0);
let amount = U256::from_str("1234567890123456789").unwrap();
let result = convert_u256_to_f64(amount, 9).unwrap();
assert!((result - 1_234_567_890.123_456_7).abs() < 1.0); }
#[rstest]
fn test_convert_u256_vs_i256_consistency() {
let u256_amount = U256::from_str("1000000000000000000").unwrap();
let i256_amount = I256::from_str("1000000000000000000").unwrap();
let u256_result = convert_u256_to_f64(u256_amount, 18).unwrap();
let i256_result = convert_i256_to_f64(i256_amount, 18).unwrap();
assert_eq!(u256_result, i256_result);
assert_eq!(u256_result, 1.0);
}
#[rstest]
fn test_convert_u256_max_values() {
let large_u256 = U256::from(2).pow(U256::from(255)); let result = convert_u256_to_f64(large_u256, 0).unwrap();
assert!(result.is_finite());
assert!(result > 0.0);
let large_u256_with_decimals = U256::from(2).pow(U256::from(60)); let result = convert_u256_to_f64(large_u256_with_decimals, 18).unwrap();
assert!(result.is_finite());
assert!(result > 1.0);
assert!(result < 2.0); }
}