#[cfg(test)]
mod tests {
use super::super::Number;
use bigdecimal::BigDecimal;
use num_bigint::BigInt;
use std::str::FromStr;
#[test]
fn test_tiny_decimal_addition() {
println!("测试高精度小数计算问题");
let tiny_decimal_str = "0.00000000000000000000000000000000000000000000000000000000000000000000001";
let tiny_number = Number::real(BigDecimal::from_str(tiny_decimal_str).unwrap());
let point_one = Number::real(BigDecimal::from_str("0.1").unwrap());
println!("极小数值: {}", tiny_number);
println!("0.1: {}", point_one);
let result = tiny_number + point_one;
println!("计算结果: {}", result);
let expected_str = "0.10000000000000000000000000000000000000000000000000000000000000000000001";
let expected = Number::real(BigDecimal::from_str(expected_str).unwrap());
println!("预期结果: {}", expected);
if result == expected {
println!("✓ 计算结果正确!");
} else {
println!("✗ 计算结果不正确!");
println!("差异分析:");
match (&result, &expected) {
(Number::Real(r1), Number::Real(r2)) => {
let diff = r1 - r2;
println!("数值差异: {}", diff);
}
_ => println!("类型不匹配"),
}
}
assert_eq!(result, expected, "高精度小数加法计算不正确");
}
#[test]
fn test_bigdecimal_precision() {
println!("\n测试 BigDecimal 精度:");
let tiny_precise = BigDecimal::new(BigInt::from(1), 71); let point_one_precise = BigDecimal::new(BigInt::from(1), 1);
println!("高精度极小数值: {}", tiny_precise);
println!("高精度 0.1: {}", point_one_precise);
let result_precise = &tiny_precise + &point_one_precise;
println!("高精度计算结果: {}", result_precise);
let tiny_number = Number::real(tiny_precise);
let point_one_number = Number::real(point_one_precise);
let result_number = tiny_number + point_one_number;
println!("Number 类型计算结果: {}", result_number);
let expected_precise = BigDecimal::new(
BigInt::from_str("10000000000000000000000000000000000000000000000000000000000000000000001").unwrap(),
71
);
let expected_number = Number::real(expected_precise);
println!("预期结果: {}", expected_number);
assert_eq!(result_number, expected_number, "高精度 BigDecimal 计算不正确");
}
#[test]
fn test_float_precision_issue() {
println!("\n浮点数版本(展示精度问题):");
let tiny_float = 1e-70_f64;
let result_float = tiny_float + 0.1;
println!("浮点数结果: {:.70}", result_float);
assert_eq!(result_float, 0.1);
let tiny_decimal = BigDecimal::new(BigInt::from(1), 70);
let point_one_decimal = BigDecimal::from_str("0.1").unwrap();
let result_decimal = &tiny_decimal + &point_one_decimal;
let expected_decimal = BigDecimal::from_str("0.1000000000000000000000000000000000000000000000000000000000000000000001").unwrap();
println!("BigDecimal 极小数: {}", tiny_decimal);
println!("BigDecimal 结果: {}", result_decimal);
println!("BigDecimal 预期: {}", expected_decimal);
assert_eq!(result_decimal, expected_decimal, "BigDecimal 应该保持完整精度");
}
#[test]
fn test_number_type_precision() {
let tiny = Number::real(BigDecimal::new(BigInt::from(1), 50));
let normal = Number::real(BigDecimal::from_str("0.5").unwrap());
let result = tiny.clone() + normal.clone();
let expected_decimal = BigDecimal::from_str("0.5").unwrap() + BigDecimal::new(BigInt::from(1), 50);
let expected = Number::real(expected_decimal);
println!("极小数: {}", tiny);
println!("普通数: {}", normal);
println!("计算结果: {}", result);
println!("预期结果: {}", expected);
assert_eq!(result, expected, "Number 类型应该保持高精度");
}
#[test]
fn test_user_reported_precision_issue() {
println!("\n测试用户报告的精度问题:");
println!("0.00000000000000000000000000000000000000000000000000000000000000000000001+0.1=0.10000000000000000555111512312578270211815834045410156250000000000000001");
println!("预期为: 0.10000000000000000000000000000000000000000000000000000000000000000000001");
let tiny_decimal = BigDecimal::new(BigInt::from(1), 71);
let tiny_number = Number::real(tiny_decimal);
let point_one = Number::real(BigDecimal::from_str("0.1").unwrap());
println!("极小数值: {}", tiny_number);
println!("0.1: {}", point_one);
let result = tiny_number + point_one;
println!("实际计算结果: {}", result);
let expected_str = "0.10000000000000000000000000000000000000000000000000000000000000000000001";
let expected = Number::real(BigDecimal::from_str(expected_str).unwrap());
println!("预期结果: {}", expected);
if result == expected {
println!("✓ 计算结果正确!");
} else {
println!("✗ 计算结果不正确!");
match (&result, &expected) {
(Number::Real(r1), Number::Real(r2)) => {
let diff = r1 - r2;
println!("数值差异: {}", diff);
println!("\n直接使用 BigDecimal 测试:");
let tiny_bd = BigDecimal::new(BigInt::from(1), 71);
let point_one_bd = BigDecimal::from_str("0.1").unwrap();
let result_bd = &tiny_bd + &point_one_bd;
let expected_bd = BigDecimal::from_str(expected_str).unwrap();
println!("BigDecimal 极小数: {}", tiny_bd);
println!("BigDecimal 0.1: {}", point_one_bd);
println!("BigDecimal 结果: {}", result_bd);
println!("BigDecimal 预期: {}", expected_bd);
println!("BigDecimal 相等: {}", result_bd == expected_bd);
}
_ => println!("类型不匹配"),
}
}
assert_eq!(result, expected, "高精度小数加法计算应该正确");
}
#[test]
fn test_rational_to_real_precision() {
println!("\n测试有理数到实数转换的精度保持:");
let rational = Number::rational(1, 3);
let tiny_real = Number::real(BigDecimal::new(BigInt::from(1), 50));
println!("有理数: {}", rational);
println!("极小实数: {}", tiny_real);
let result = rational + tiny_real;
println!("计算结果: {}", result);
let one_third = BigDecimal::new(BigInt::from(1), 0) / BigDecimal::new(BigInt::from(3), 0);
let tiny_part = BigDecimal::new(BigInt::from(1), 50);
let expected_decimal = one_third + tiny_part;
let expected = Number::real(expected_decimal);
println!("预期结果: {}", expected);
assert_eq!(result, expected, "有理数到实数的转换应该保持精度");
}
#[test]
fn test_mixed_precision_addition() {
println!("\n测试混合精度加法:");
let tiny1 = Number::real(BigDecimal::new(BigInt::from(1), 71));
let point_one_str = Number::real(BigDecimal::from_str("0.1").unwrap());
let result1 = tiny1 + point_one_str;
let tiny2 = Number::real(BigDecimal::new(BigInt::from(1), 71));
let point_one_rational = Number::rational(1, 10);
let result2 = tiny2 + point_one_rational;
let tiny3 = Number::real(BigDecimal::new(BigInt::from(1), 71));
let point_one_float = Number::float(0.1);
let result3 = tiny3 + point_one_float;
println!("方式1 (字符串): {}", result1);
println!("方式2 (有理数): {}", result2);
println!("方式3 (浮点数): {}", result3);
let expected_str = "0.10000000000000000000000000000000000000000000000000000000000000000000001";
let expected = Number::real(BigDecimal::from_str(expected_str).unwrap());
println!("预期结果: {}", expected);
assert_eq!(result1, expected, "字符串方式应该保持精度");
assert_eq!(result2, expected, "有理数方式应该保持精度");
if result3 != expected {
println!("✓ 浮点数方式确实有精度损失,这是预期的");
}
}
}