Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,79 @@
|
||||
// 独立 Rust 参照直接使用相同版本的 dec,逐项清理和检查状态。
|
||||
// 两侧使用同一输入、Decimal128 精度、舍入和顺序,不用二进制浮点代替。
|
||||
|
||||
fn generated(values: &[Decimal]) -> Result<Decimal, Fault> {
|
||||
GENERATED_DECIMAL_SUM(values)
|
||||
}
|
||||
|
||||
fn reference(values: &[Decimal]) -> Result<Decimal, Fault> {
|
||||
let mut context = dec::Context::<dec::Decimal128>::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::<Vec<_>>();
|
||||
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::<Vec<_>>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user