1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use honggfuzz::fuzz;
use sp_arithmetic::{traits::SaturatedConversion, PerThing, PerU16, Perbill, Percent, Perquintill};
fn main() {
loop {
fuzz!(|data: ((u16, u16), (u32, u32), (u64, u64))| {
let (u16_pair, u32_pair, u64_pair) = data;
let (smaller, bigger) = (u16_pair.0.min(u16_pair.1), u16_pair.0.max(u16_pair.1));
let ratio = PerU16::from_rational(smaller, bigger);
assert_per_thing_equal_error(
ratio,
PerU16::from_float(smaller as f64 / bigger.max(1) as f64),
1,
);
let (smaller, bigger) = (u32_pair.0.min(u32_pair.1), u32_pair.0.max(u32_pair.1));
let ratio = PerU16::from_rational(smaller, bigger);
assert_per_thing_equal_error(
ratio,
PerU16::from_float(smaller as f64 / bigger.max(1) as f64),
1,
);
let (smaller, bigger) = (u64_pair.0.min(u64_pair.1), u64_pair.0.max(u64_pair.1));
let ratio = PerU16::from_rational(smaller, bigger);
assert_per_thing_equal_error(
ratio,
PerU16::from_float(smaller as f64 / bigger.max(1) as f64),
1,
);
let (smaller, bigger) = (u16_pair.0.min(u16_pair.1), u16_pair.0.max(u16_pair.1));
let ratio = Percent::from_rational(smaller, bigger);
assert_per_thing_equal_error(
ratio,
Percent::from_float(smaller as f64 / bigger.max(1) as f64),
1,
);
let (smaller, bigger) = (u32_pair.0.min(u32_pair.1), u32_pair.0.max(u32_pair.1));
let ratio = Percent::from_rational(smaller, bigger);
assert_per_thing_equal_error(
ratio,
Percent::from_float(smaller as f64 / bigger.max(1) as f64),
1,
);
let (smaller, bigger) = (u64_pair.0.min(u64_pair.1), u64_pair.0.max(u64_pair.1));
let ratio = Percent::from_rational(smaller, bigger);
assert_per_thing_equal_error(
ratio,
Percent::from_float(smaller as f64 / bigger.max(1) as f64),
1,
);
let (smaller, bigger) = (u32_pair.0.min(u32_pair.1), u32_pair.0.max(u32_pair.1));
let ratio = Perbill::from_rational(smaller, bigger);
assert_per_thing_equal_error(
ratio,
Perbill::from_float(smaller as f64 / bigger.max(1) as f64),
100,
);
let (smaller, bigger) = (u64_pair.0.min(u64_pair.1), u64_pair.0.max(u64_pair.1));
let ratio = Perbill::from_rational(smaller, bigger);
assert_per_thing_equal_error(
ratio,
Perbill::from_float(smaller as f64 / bigger.max(1) as f64),
100,
);
let (smaller, bigger) = (u64_pair.0.min(u64_pair.1), u64_pair.0.max(u64_pair.1));
let ratio = Perquintill::from_rational(smaller, bigger);
assert_per_thing_equal_error(
ratio,
Perquintill::from_float(smaller as f64 / bigger.max(1) as f64),
1000,
);
})
}
}
fn assert_per_thing_equal_error<P: PerThing>(a: P, b: P, err: u128) {
let a_abs = a.deconstruct().saturated_into::<u128>();
let b_abs = b.deconstruct().saturated_into::<u128>();
let diff = a_abs.max(b_abs) - a_abs.min(b_abs);
assert!(diff <= err, "{:?} !~ {:?}", a, b);
}