105 lines
4.2 KiB
Rust
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);
|
|
}
|