-
Notifications
You must be signed in to change notification settings - Fork 72
/
math.rs
47 lines (43 loc) · 1.43 KB
/
math.rs
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
///! 128 and 256 bit numbers
///! U128 is more efficient that u128
///! https://github.com/solana-labs/solana/issues/19549
use uint::construct_uint;
construct_uint! {
pub struct U128(2);
}
construct_uint! {
pub struct U256(4);
}
pub trait CheckedCeilDiv: Sized {
/// Perform ceiling division
fn checked_ceil_div(&self, rhs: Self) -> Option<(Self, Self)>;
}
impl CheckedCeilDiv for u128 {
fn checked_ceil_div(&self, mut rhs: Self) -> Option<(Self, Self)> {
let mut quotient = self.checked_div(rhs)?;
// Avoid dividing a small number by a big one and returning 1, and instead
// fail.
if quotient == 0 {
// return None;
if self.checked_mul(2 as u128)? >= rhs {
return Some((1, 0));
} else {
return Some((0, 0));
}
}
// Ceiling the destination amount if there's any remainder, which will
// almost always be the case.
let remainder = self.checked_rem(rhs)?;
if remainder > 0 {
quotient = quotient.checked_add(1)?;
// calculate the minimum amount needed to get the dividend amount to
// avoid truncating too much
rhs = self.checked_div(quotient)?;
let remainder = self.checked_rem(quotient)?;
if remainder > 0 {
rhs = rhs.checked_add(1)?;
}
}
Some((quotient, rhs))
}
}