// 独立 Rust 参照直接使用相同版本的 dec,逐项清理和检查状态。 // 两侧使用同一输入、Decimal128 精度、舍入和顺序,不用二进制浮点代替。 fn generated(values: &[Decimal]) -> Result { GENERATED_DECIMAL_SUM(values) } fn reference(values: &[Decimal]) -> Result { let mut context = dec::Context::::default(); let mut total = dec::Decimal128::ZERO; for value in values { context.clear_status(); total = context.add(total, dec::Decimal128::from_be_bytes(value.to_be_bytes())); if !total.is_finite() || context.status().overflow() || context.status().invalid_operation() { return Err(&FaultInfo { message: "Decimal fault", source: "Rust reference", line: 0, column: 0, }); } } Ok(Decimal::from_be_bytes(total.to_be_bytes())) } fn score(value: &Decimal) -> u64 { u64::from_be_bytes(value.to_be_bytes()[8..].try_into().unwrap()) } fn main() { let maximum = Decimal::parse("9.999999999999999999999999999999999E+6144").unwrap(); let zero = Decimal::from_int(0); for values in [ vec![maximum, maximum, -maximum], vec![-maximum, -maximum, maximum], vec![zero], Vec::new(), ] { let actual = generated(&values); let expected = reference(&values); assert_eq!(actual.is_err(), expected.is_err()); if let (Ok(actual), Ok(expected)) = (actual, expected) { assert_eq!(actual.to_be_bytes(), expected.to_be_bytes()); } } let short = [ "0.1", "0.2", "-0.05", "1.25", "-0.00", "10", "-2.50", "0.001", ] .map(|text| Decimal::parse(text).unwrap()); let integers = (0..256).map(Decimal::from_int).collect::>(); let palette = [ "-1234567890123456789012345678901234", "1.000000000000000000000000000000001", "-0.001", "-1E-6176", "-0.00", "0E+100", "1E-6176", "0.9999999999999999999999999999999999", "1234567890123456789012345678901234", ] .map(|text| Decimal::parse(text).unwrap()); let mixed = (0..256) .map(|index| palette[index % palette.len()]) .collect::>(); println!("case,sample,implementation,elapsed_ns,checksum"); for (name, values, count) in [ ("decimal_sum_short", short.as_slice(), 10000), ("decimal_sum_integers", integers.as_slice(), 1000), ("decimal_sum_mixed", mixed.as_slice(), 1000), ] { assert_eq!( generated(values).unwrap().to_be_bytes(), reference(values).unwrap().to_be_bytes() ); compare(name, values, count, generated, reference, score); } }