balancer_maths_rust/pools/gyro/
signed_fixed_point.rs1use alloy_primitives::{uint, I256};
2
3pub const ONE: I256 = I256::from_raw(uint!(1000000000000000000_U256)); pub const ONE_E_19: I256 = I256::from_raw(uint!(10000000000000000000_U256)); pub const ONE_XP: I256 = I256::from_raw(uint!(100000000000000000000000000000000000000_U256)); #[derive(Debug)]
8pub struct FixedPointError(pub &'static str);
9
10pub fn mul_down_mag(a: &I256, b: &I256) -> I256 {
11 (*a * *b) / ONE
12}
13
14pub fn mul_up_mag(a: &I256, b: &I256) -> I256 {
15 let product = *a * *b;
16 if product > I256::ZERO {
17 (product - I256::ONE) / ONE + I256::ONE
18 } else if product < I256::ZERO {
19 (product + I256::ONE) / ONE - I256::ONE
20 } else {
21 I256::ZERO
22 }
23}
24
25pub fn div_down_mag(a: &I256, b: &I256) -> I256 {
26 if b.is_zero() {
27 panic!("ZeroDivision");
28 }
29 if a.is_zero() {
30 return I256::ZERO;
31 }
32 let a_inflated = *a * ONE;
33 a_inflated / *b
34}
35
36pub fn div_up_mag(a: &I256, b: &I256) -> I256 {
37 if b.is_zero() {
38 panic!("ZeroDivision");
39 }
40 if a.is_zero() {
41 return I256::ZERO;
42 }
43 let mut local_a = *a;
44 let mut local_b = *b;
45 if b < &I256::ZERO {
46 local_b = -local_b;
47 local_a = -local_a;
48 }
49 let a_inflated = local_a * ONE;
50 if a_inflated > I256::ZERO {
51 (a_inflated - I256::ONE) / local_b + I256::ONE
52 } else {
53 (a_inflated + I256::ONE) / local_b - I256::ONE
54 }
55}
56
57pub fn mul_xp_u(a: &I256, b: &I256) -> I256 {
59 (*a * *b) / ONE_XP
60}
61
62pub fn div_xp_u(a: &I256, b: &I256) -> I256 {
63 if b.is_zero() {
64 panic!("ZeroDivision");
65 }
66 (*a * ONE_XP) / *b
67}
68
69pub fn mul_down_xp_to_np(a: &I256, b: &I256) -> I256 {
70 let b1 = *b / ONE_E_19;
71 let b2 = *b % ONE_E_19;
72 let prod1 = *a * b1;
73 let prod2 = *a * b2;
74
75 if prod1 >= I256::ZERO && prod2 >= I256::ZERO {
76 let prod2_div_e19 = prod2 / ONE_E_19;
77 (prod1 + prod2_div_e19) / ONE_E_19
78 } else {
79 let prod2_div_e19 = prod2 / ONE_E_19;
80 (prod1 + prod2_div_e19 + I256::ONE) / ONE_E_19 - I256::ONE
81 }
82}
83
84pub fn mul_up_xp_to_np(a: &I256, b: &I256) -> I256 {
85 let b1 = *b / ONE_E_19;
86 let b2 = *b % ONE_E_19;
87 let prod1 = *a * b1;
88 let prod2 = *a * b2;
89
90 if prod1 <= I256::ZERO && prod2 <= I256::ZERO {
91 let prod2_div_e19 = prod2 / ONE_E_19;
92 (prod1 + prod2_div_e19) / ONE_E_19
93 } else {
94 let prod2_div_e19 = prod2 / ONE_E_19;
95 (prod1 + prod2_div_e19 - I256::ONE) / ONE_E_19 + I256::ONE
96 }
97}