Files
core/test/rust/performance/numeric/mod.rs
T
2026-11-03 03:32:07 +00:00

105 lines
4.2 KiB
Rust

fn decimal_generated(values: &[Option<Decimal>]) -> Result<i64, Fault> {
let mut total = 0i64;
for value in values {
total += GENERATED_DECIMAL(value)?;
}
Ok(total)
}
fn decimal_reference(values: &[Option<Decimal>]) -> Result<i64, Fault> {
let mut total = 0i64;
let zero = Decimal::from_int(0);
for value in values {
total += match value {
None => 2,
Some(value) if *value < zero => -1,
Some(value) if *value == zero => 0,
Some(_) => 1,
};
}
Ok(total)
}
fn edge_generated(values: &[Decimal]) -> Result<i64, Fault> {
let mut total = 0i64;
for value in values {
total += GENERATED_EDGE(*value)?;
}
Ok(total)
}
fn edge_reference(values: &[Decimal]) -> Result<i64, Fault> {
let mut total = 0i64;
let one = Decimal::from_int(1);
for value in values {
total += i64::from(*value > one);
}
Ok(total)
}
fn float_generated(values: &[Option<f64>]) -> Result<i64, Fault> {
let mut total = 0i64;
for value in values {
total += GENERATED_FLOAT(value)?;
}
Ok(total)
}
fn float_reference(values: &[Option<f64>]) -> Result<i64, Fault> {
let mut total = 0i64;
for value in values {
total += match value {
None => -1,
Some(value) if *value == 1.0 => 1,
Some(value) if *value == 0.0 => 0,
Some(_) => 2,
};
}
Ok(total)
}
fn main() {
let decimals = (0..256).map(|index| match index % 4 {
0 => None,
1 => Some(Decimal::from_int(-(index as i64))),
2 => Some(Decimal::from_int(0)),
_ => Some(Decimal::from_int(index as i64)),
}).collect::<Vec<_>>();
let edges = ["0", "1", "1.000000000000000000000000000000001", "2"];
let edges = (0..256).map(|index| Decimal::parse(edges[index % 4]).unwrap()).collect::<Vec<_>>();
let special = [None, Some(0.0), Some(-0.0), Some(1.0), Some(-1.0), Some(f64::NAN), Some(f64::INFINITY), Some(f64::NEG_INFINITY)];
let floats = (0..256).map(|index| special[index % special.len()]).collect::<Vec<_>>();
for value in &decimals { assert_eq!(GENERATED_DECIMAL(value).unwrap(), decimal_reference(&[*value]).unwrap()); }
for value in &edges { assert_eq!(GENERATED_EDGE(*value).unwrap(), edge_reference(&[*value]).unwrap()); }
for value in &floats { assert_eq!(GENERATED_FLOAT(value).unwrap(), float_reference(&[*value]).unwrap()); }
println!("case,sample,implementation,elapsed_ns,checksum");
compare("decimal_clauses", &decimals, 10000, decimal_generated, decimal_reference, |value| *value as u64);
compare("decimal_adjacent", &edges, 10000, edge_generated, edge_reference, |value| *value as u64);
compare("float_clauses", &floats, 10000, float_generated, float_reference, |value| *value as u64);
// 独立保留原三组;混合输入覆盖非整数、不同小数位、负零和指数极限。
let spellings = [
"-9.999999999999999999999999999999999E+6144",
"-1234567890123456789012345678901234",
"-1.000000000000000000000000000000001",
"-1.00", "-0.001", "-1E-6176", "-0.00", "0", "0E+100",
"1E-6176", "0.001", "0.9999999999999999999999999999999999",
"1", "1.000", "1.000000000000000000000000000000001",
"1234567890123456789012345678901234",
"9.999999999999999999999999999999999E+6144",
];
let palette = spellings.map(|text| Decimal::parse(text).unwrap());
let mut state = 0x123456789abcdef0u64;
let mixed = (0..256).map(|_| {
state = state.wrapping_mul(6364136223846793005).wrapping_add(1);
palette[((state >> 32) as usize) % palette.len()]
}).collect::<Vec<_>>();
let nullable = mixed.iter().enumerate().map(|(index, value)| {
if index % 5 == 0 { None } else { Some(*value) }
}).collect::<Vec<_>>();
for value in &nullable { assert_eq!(GENERATED_DECIMAL(value).unwrap(), decimal_reference(&[*value]).unwrap()); }
for value in &mixed { assert_eq!(GENERATED_EDGE(*value).unwrap(), edge_reference(&[*value]).unwrap()); }
compare("decimal_mixed_clauses", &nullable, 10000, decimal_generated, decimal_reference, |value| *value as u64);
compare("decimal_mixed_adjacent", &mixed, 10000, edge_generated, edge_reference, |value| *value as u64);
}