mech_core/types/
rational_numbers.rs1use crate::*;
2use super::*;
3
4#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, PartialOrd)]
8pub struct R64(pub Rational64);
9
10impl R64 {
11 pub fn new(numer: i64, denom: i64) -> R64 {
12 R64(Rational64::new(numer, denom))
13 }
14
15 pub fn from_le_bytes(bytes: &[u8; 16]) -> R64 {
16 let numer = match bytes[0..8].try_into() {
17 Ok(arr) => i64::from_le_bytes(arr),
18 Err(_) => panic!("Failed to read numerator from bytes"),
19 };
20 let denom = match bytes[8..16].try_into() {
21 Ok(arr) => i64::from_le_bytes(arr),
22 Err(_) => panic!("Failed to read denominator from bytes"),
23 };
24 if denom == 0 {
25 panic!("Denominator cannot be zero");
26 }
27 R64(Rational64::new(numer, denom))
28 }
29
30 pub fn from_f64(f: f64) -> Option<R64> {
31 match Rational64::from_f64(f) {
32 Some(r) => Some(R64(r)),
33 None => None,
34 }
35 }
36
37 pub fn to_f64(&self) -> Option<f64> {
38 match self.0.to_f64() {
39 Some(val) => Some(val),
40 None => None,
41 }
42 }
43
44 pub fn numer(&self) -> &i64 {
45 self.0.numer()
46 }
47
48 pub fn denom(&self) -> &i64 {
49 self.0.denom()
50 }
51}
52
53impl std::fmt::Display for R64 {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 write!(f, "{}", self.pretty_print())
56 }
57}
58
59
60impl Default for R64 {
61 fn default() -> Self {
62 R64(Rational64::default())
63 }
64}
65
66
67impl PrettyPrint for R64 {
68 fn pretty_print(&self) -> String {
69 format!("{}/{}", self.numer(), self.denom())
70 }
71}
72
73impl Mul<R64> for R64 {
74 type Output = R64;
75 fn mul(self, other: R64) -> R64 {
76 R64(self.0 * other.0)
77 }
78}
79
80impl One for R64 {
81 fn one() -> Self {
82 R64(Rational64::one())
83 }
84 fn is_one(&self) -> bool {
85 self.0.is_one()
86 }
87}
88
89impl Add<R64> for R64 {
90 type Output = R64;
91 fn add(self, other: R64) -> R64 {
92 R64(self.0 + other.0)
93 }
94}
95
96impl AddAssign<R64> for R64 {
97 fn add_assign(&mut self, other: R64) {
98 self.0 += other.0;
99 }
100}
101
102impl Sub<R64> for R64 {
103 type Output = R64;
104 fn sub(self, other: R64) -> R64 {
105 R64(self.0 - other.0)
106 }
107}
108
109impl Div<R64> for R64 {
110 type Output = R64;
111 fn div(self, other: R64) -> R64 {
112 R64(self.0 / other.0)
113 }
114}
115
116impl DivAssign<R64> for R64 {
117 fn div_assign(&mut self, other: R64) {
118 self.0 /= other.0;
119 }
120}
121
122
123impl SubAssign<R64> for R64 {
124 fn sub_assign(&mut self, other: R64) {
125 self.0 -= other.0;
126 }
127}
128
129impl MulAssign<R64> for R64 {
130 fn mul_assign(&mut self, other: R64) {
131 self.0 *= other.0;
132 }
133}
134
135impl Zero for R64 {
136 fn zero() -> Self {
137 R64(Rational64::zero())
138 }
139 fn is_zero(&self) -> bool {
140 self.0.is_zero()
141 }
142}
143
144impl Neg for R64 {
145 type Output = Self;
146 fn neg(self) -> Self::Output {
147 R64(-self.0)
148 }
149}
150
151#[cfg(feature = "f64")]
152impl From<R64> for F64 {
153 fn from(r: R64) -> Self {
154 F64::new(r.0.to_f64().unwrap())
155 }
156}
157
158#[cfg(feature = "f64")]
159impl From<F64> for R64 {
160 fn from(f: F64) -> Self {
161 R64(Rational64::from_f64(f.0).unwrap())
162 }
163}
164
165impl ToUsize for R64 {
166 fn to_usize(&self) -> usize {
167 self.0.to_integer() as usize
168 }
169}
170
171impl ToValue for R64 {
172 fn to_value(&self) -> Value {
173 Value::R64(Ref::new(*self))
174 }
175}