fn decimal_generated(values: &[Option]) -> Result { let mut total = 0i64; for value in values { total += GENERATED_DECIMAL(value)?; } Ok(total) } fn decimal_reference(values: &[Option]) -> Result { 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 { let mut total = 0i64; for value in values { total += GENERATED_EDGE(*value)?; } Ok(total) } fn edge_reference(values: &[Decimal]) -> Result { 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]) -> Result { let mut total = 0i64; for value in values { total += GENERATED_FLOAT(value)?; } Ok(total) } fn float_reference(values: &[Option]) -> Result { 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::>(); let edges = ["0", "1", "1.000000000000000000000000000000001", "2"]; let edges = (0..256).map(|index| Decimal::parse(edges[index % 4]).unwrap()).collect::>(); 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::>(); 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::>(); let nullable = mixed.iter().enumerate().map(|(index, value)| { if index % 5 == 0 { None } else { Some(*value) } }).collect::>(); 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); }