clean arithmetic and unify names with the new api (#8581)

This commit is contained in:
Kian Paimani
2021-04-09 16:36:06 +02:00
committed by GitHub
parent 7e59d172b8
commit 373e3a4ddc
6 changed files with 30 additions and 32 deletions
+1
View File
@@ -8570,6 +8570,7 @@ dependencies = [
"serde_json",
"sp-debug-derive",
"sp-std",
"static_assertions",
]
[[package]]
+1 -1
View File
@@ -74,7 +74,7 @@ mod multiplier_tests {
let m = max_normal() as f64;
// block weight always truncated to max weight
let block_weight = (block_weight as f64).min(m);
let v: f64 = AdjustmentVariable::get().to_fraction();
let v: f64 = AdjustmentVariable::get().to_float();
// Ideal saturation in terms of weight
let ss = target() as f64;
@@ -117,17 +117,17 @@ fn format_weight(field: &Ident) -> TokenStream {
&if self.#field > 1_000_000_000 {
format!(
"{:.1?} ms",
Fixed::saturating_from_rational(self.#field, 1_000_000_000).to_fraction()
Fixed::saturating_from_rational(self.#field, 1_000_000_000).to_float()
)
} else if self.#field > 1_000_000 {
format!(
"{:.1?} µs",
Fixed::saturating_from_rational(self.#field, 1_000_000).to_fraction()
Fixed::saturating_from_rational(self.#field, 1_000_000).to_float()
)
} else if self.#field > 1_000 {
format!(
"{:.1?} ns",
Fixed::saturating_from_rational(self.#field, 1_000).to_fraction()
Fixed::saturating_from_rational(self.#field, 1_000).to_float()
)
} else {
format!("{} ps", self.#field)
@@ -17,6 +17,7 @@ targets = ["x86_64-unknown-linux-gnu"]
[dependencies]
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] }
integer-sqrt = "0.1.2"
static_assertions = "1.1.0"
num-traits = { version = "0.2.8", default-features = false }
sp-std = { version = "3.0.0", default-features = false, path = "../std" }
serde = { version = "1.0.101", optional = true, features = ["derive"] }
+23 -27
View File
@@ -33,6 +33,10 @@ const SHIFT: usize = 32;
/// short form of _Base_. Analogous to the value 10 in base-10 decimal numbers.
const B: Double = Single::max_value() as Double + 1;
static_assertions::const_assert!(
sp_std::mem::size_of::<Double>() - sp_std::mem::size_of::<Single>() == SHIFT / 8
);
/// Splits a [`Double`] limb number into a tuple of two [`Single`] limb numbers.
pub fn split(a: Double) -> (Single, Single) {
let al = a as Single;
@@ -187,6 +191,7 @@ impl BigUint {
let u = Double::from(self.checked_get(j).unwrap_or(0));
let v = Double::from(other.checked_get(j).unwrap_or(0));
let s = u + v + k;
// proof: any number % B will fit into `Single`.
w.set(j, (s % B) as Single);
k = s / B;
}
@@ -209,28 +214,24 @@ impl BigUint {
let s = {
let u = Double::from(self.checked_get(j).unwrap_or(0));
let v = Double::from(other.checked_get(j).unwrap_or(0));
let mut needs_borrow = false;
let mut t = 0;
if let Some(v1) = u.checked_sub(v) {
if let Some(v2) = v1.checked_sub(k) {
t = v2;
k = 0;
} else {
needs_borrow = true;
}
if let Some(v2) = u.checked_sub(v).and_then(|v1| v1.checked_sub(k)) {
// no borrow is needed. u - v - k can be computed as-is
let t = v2;
k = 0;
t
} else {
needs_borrow = true;
}
if needs_borrow {
t = u + B - v - k;
// borrow is needed. Add a `B` to u, before subtracting.
// PROOF: addition: `u + B < 2*B`, thus can fit in double.
// PROOF: subtraction: if `u - v - k < 0`, then `u + B - v - k < B`.
// NOTE: the order of operations is critical to ensure underflow won't happen.
let t = u + B - v - k;
k = 1;
t
}
t
};
// PROOF: t either comes from `v2`, or from `u + B - v - k`. The former is
// trivial. The latter will not overflow this branch will only happen if the sum of
// `u - v - k` part has been negative, hence `u + B - v - k < B`.
w.set(j, s as Single);
}
@@ -264,10 +265,9 @@ impl BigUint {
let mut k = 0;
for i in 0..m {
// PROOF: (B1) × (B1) + (B1) + (B1) = B^2 1 < B^2. addition is safe.
let t =
mul_single(self.get(j), other.get(i))
+ Double::from(w.get(i + j))
+ Double::from(k);
let t = mul_single(self.get(j), other.get(i))
+ Double::from(w.get(i + j))
+ Double::from(k);
w.set(i + j, (t % B) as Single);
// PROOF: (B^2 - 1) / B < B. conversion is safe.
k = (t / B) as Single;
@@ -580,12 +580,6 @@ pub mod tests {
BigUint { digits: vec![1; n] }
}
#[test]
fn shift_check() {
let shift = sp_std::mem::size_of::<Double>() - sp_std::mem::size_of::<Single>();
assert_eq!(shift * 8, SHIFT);
}
#[test]
fn split_works() {
let a = SHIFT / 2;
@@ -732,12 +726,14 @@ pub mod tests {
let c = BigUint { digits: vec![1, 1, 2] };
let d = BigUint { digits: vec![0, 2] };
let e = BigUint { digits: vec![0, 1, 1, 2] };
let f = BigUint { digits: vec![7, 8] };
assert!(a.clone().div(&b, true).is_none());
assert!(c.clone().div(&a, true).is_none());
assert!(c.clone().div(&d, true).is_none());
assert!(e.clone().div(&a, true).is_none());
assert!(f.clone().div(&b, true).is_none());
assert!(c.clone().div(&b, true).is_some());
}
@@ -381,7 +381,7 @@ macro_rules! implement_fixed {
}
#[cfg(any(feature = "std", test))]
pub fn to_fraction(self) -> f64 {
pub fn to_float(self) -> f64 {
self.0 as f64 / <Self as FixedPointNumber>::DIV as f64
}
}