Skip to content
Snippets Groups Projects
Commit fbc4e7f0 authored by Xiliang Chen's avatar Xiliang Chen Committed by GitHub
Browse files

fix Fixed64 (#5784)

* fix fixed64

* improve

* bump version
parent 15e33c46
No related merge requests found
......@@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
// implementation changes and behavior does not, then leave spec_version as
// is and increment impl_version.
spec_version: 244,
impl_version: 1,
impl_version: 2,
apis: RUNTIME_API_VERSIONS,
transaction_version: 1,
};
......
......@@ -113,7 +113,10 @@ impl Saturating for Fixed64 {
}
fn saturating_mul(self, rhs: Self) -> Self {
Self(self.0.saturating_mul(rhs.0) / DIV)
let a = self.0 as i128;
let b = rhs.0 as i128;
let res = a * b / DIV as i128;
Self(res.saturated_into())
}
fn saturating_sub(self, rhs: Self) -> Self {
......@@ -121,7 +124,22 @@ impl Saturating for Fixed64 {
}
fn saturating_pow(self, exp: usize) -> Self {
Self(self.0.saturating_pow(exp as u32))
if exp == 0 {
return Self::from_natural(1);
}
let exp = exp as u64;
let msb_pos = 64 - exp.leading_zeros();
let mut result = Self::from_natural(1);
let mut pow_val = self;
for i in 0..msb_pos {
if ((1 << i) & exp) > 0 {
result = result.saturating_mul(pow_val);
}
pow_val = pow_val.saturating_mul(pow_val);
}
result
}
}
......@@ -333,4 +351,32 @@ mod tests {
let b = Fixed64::from_rational(1, 100);
assert_eq!(a.checked_div(&b), Some(Fixed64::from_rational(120, 1)));
}
#[test]
fn saturating_mul_should_work() {
assert_eq!(Fixed64::from_natural(100).saturating_mul(Fixed64::from_natural(100)), Fixed64::from_natural(10000));
}
#[test]
fn saturating_pow_should_work() {
assert_eq!(Fixed64::from_natural(2).saturating_pow(0), Fixed64::from_natural(1));
assert_eq!(Fixed64::from_natural(2).saturating_pow(1), Fixed64::from_natural(2));
assert_eq!(Fixed64::from_natural(2).saturating_pow(2), Fixed64::from_natural(4));
assert_eq!(Fixed64::from_natural(2).saturating_pow(3), Fixed64::from_natural(8));
assert_eq!(Fixed64::from_natural(2).saturating_pow(20), Fixed64::from_natural(1048576));
assert_eq!(Fixed64::from_natural(1).saturating_pow(1000), Fixed64::from_natural(1));
assert_eq!(Fixed64::from_natural(-1).saturating_pow(1000), Fixed64::from_natural(1));
assert_eq!(Fixed64::from_natural(-1).saturating_pow(1001), Fixed64::from_natural(-1));
assert_eq!(Fixed64::from_natural(1).saturating_pow(usize::max_value()), Fixed64::from_natural(1));
assert_eq!(Fixed64::from_natural(-1).saturating_pow(usize::max_value()), Fixed64::from_natural(-1));
assert_eq!(Fixed64::from_natural(-1).saturating_pow(usize::max_value() - 1), Fixed64::from_natural(1));
assert_eq!(Fixed64::from_natural(309).saturating_pow(4), Fixed64::from_natural(9_116_621_361));
assert_eq!(Fixed64::from_natural(309).saturating_pow(5), Fixed64::from_parts(i64::max_value()));
assert_eq!(Fixed64::from_natural(1).saturating_pow(usize::max_value()), Fixed64::from_natural(1));
assert_eq!(Fixed64::from_natural(0).saturating_pow(usize::max_value()), Fixed64::from_natural(0));
assert_eq!(Fixed64::from_natural(2).saturating_pow(usize::max_value()), Fixed64::from_parts(i64::max_value()));
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment