defituna_core/math/
fixed.rs1use fusionamm_core::{CoreError, ARITHMETIC_OVERFLOW};
2
3pub enum Rounding {
4 Up,
5 Down,
6}
7
8pub fn mul_div_64(x: u64, y: u64, d: u64, rounding: Rounding) -> Result<u64, CoreError> {
13 let x_128 = x as u128;
14 let y_128 = y as u128;
15 let d_128 = d as u128;
16
17 match rounding {
18 Rounding::Up => {
19 let result = (x_128 * y_128)
20 .checked_add(d_128.checked_sub(1).ok_or(ARITHMETIC_OVERFLOW)?)
21 .ok_or(ARITHMETIC_OVERFLOW)?
22 .checked_div(d_128)
23 .ok_or(ARITHMETIC_OVERFLOW)?
24 .try_into()
25 .map_err(|_| ARITHMETIC_OVERFLOW)?;
26 Ok(result)
27 }
28
29 Rounding::Down => {
30 let result: u64 = (x_128 * y_128)
31 .checked_div(d_128)
32 .ok_or(ARITHMETIC_OVERFLOW)?
33 .try_into()
34 .map_err(|_| ARITHMETIC_OVERFLOW)?;
35 Ok(result)
36 }
37 }
38}