equal
deleted
inserted
replaced
1 use std::{cmp, ops, ops::Shl}; |
1 use std::{cmp, ops}; |
|
2 use saturate::SaturatingInto; |
2 |
3 |
3 const POSITIVE_MASK: u64 = 0x0000_0000_0000_0000; |
4 const POSITIVE_MASK: u64 = 0x0000_0000_0000_0000; |
4 const NEGATIVE_MASK: u64 = 0xFFFF_FFFF_FFFF_FFFF; |
5 const NEGATIVE_MASK: u64 = 0xFFFF_FFFF_FFFF_FFFF; |
5 |
6 |
6 #[inline] |
7 #[inline] |
64 |
65 |
65 #[inline] |
66 #[inline] |
66 pub fn sqr(&self) -> Self { |
67 pub fn sqr(&self) -> Self { |
67 Self { |
68 Self { |
68 sign_mask: 0, |
69 sign_mask: 0, |
69 value: ((self.value as u128).pow(2) >> 32) as u64, |
70 value: ((self.value as u128).pow(2) >> 32).saturating_into(), |
70 } |
71 } |
71 } |
72 } |
72 |
73 |
73 #[inline] |
74 #[inline] |
74 pub fn sqrt(&self) -> Self { |
75 pub fn sqrt(&self) -> Self { |
147 |
148 |
148 impl Eq for FPNum {} |
149 impl Eq for FPNum {} |
149 |
150 |
150 impl PartialOrd for FPNum { |
151 impl PartialOrd for FPNum { |
151 #[inline] |
152 #[inline] |
152 fn partial_cmp(&self, rhs: &Self) -> std::option::Option<std::cmp::Ordering> { |
153 fn partial_cmp(&self, rhs: &Self) -> Option<cmp::Ordering> { |
153 Some(self.cmp(rhs)) |
154 Some(self.cmp(rhs)) |
154 } |
155 } |
155 } |
156 } |
156 |
157 |
157 impl Ord for FPNum { |
158 impl Ord for FPNum { |
202 |
203 |
203 #[inline] |
204 #[inline] |
204 fn mul(self, rhs: Self) -> Self { |
205 fn mul(self, rhs: Self) -> Self { |
205 Self { |
206 Self { |
206 sign_mask: self.sign_mask ^ rhs.sign_mask, |
207 sign_mask: self.sign_mask ^ rhs.sign_mask, |
207 value: ((self.value as u128 * rhs.value as u128) >> 32) as u64, |
208 value: ((self.value as u128 * rhs.value as u128) >> 32).saturating_into(), |
208 } |
209 } |
209 } |
210 } |
210 } |
211 } |
211 |
212 |
212 impl ops::Mul<i32> for FPNum { |
213 impl ops::Mul<i32> for FPNum { |
214 |
215 |
215 #[inline] |
216 #[inline] |
216 fn mul(self, rhs: i32) -> Self { |
217 fn mul(self, rhs: i32) -> Self { |
217 Self { |
218 Self { |
218 sign_mask: self.sign_mask ^ bool_mask(rhs < 0), |
219 sign_mask: self.sign_mask ^ bool_mask(rhs < 0), |
219 value: self.value * rhs.abs() as u64, |
220 value: (self.value as u128 * rhs.abs() as u128).saturating_into(), |
220 } |
221 } |
221 } |
222 } |
222 } |
223 } |
223 |
224 |
224 impl ops::Div for FPNum { |
225 impl ops::Div for FPNum { |
226 |
227 |
227 #[inline] |
228 #[inline] |
228 fn div(self, rhs: Self) -> Self { |
229 fn div(self, rhs: Self) -> Self { |
229 Self { |
230 Self { |
230 sign_mask: self.sign_mask ^ rhs.sign_mask, |
231 sign_mask: self.sign_mask ^ rhs.sign_mask, |
231 value: (((self.value as u128) << 32) / rhs.value as u128) as u64, |
232 value: (((self.value as u128) << 32) / rhs.value as u128).saturating_into(), |
232 } |
233 } |
233 } |
234 } |
234 } |
235 } |
235 |
236 |
236 impl ops::Div<i32> for FPNum { |
237 impl ops::Div<i32> for FPNum { |
324 self.x().is_zero() && self.y().is_zero() |
325 self.x().is_zero() && self.y().is_zero() |
325 } |
326 } |
326 |
327 |
327 #[inline] |
328 #[inline] |
328 pub fn max_norm(&self) -> FPNum { |
329 pub fn max_norm(&self) -> FPNum { |
329 std::cmp::max(self.x().abs(), self.y().abs()) |
330 cmp::max(self.x().abs(), self.y().abs()) |
330 } |
331 } |
331 |
332 |
332 #[inline] |
333 #[inline] |
333 pub fn sqr_distance(&self) -> FPNum { |
334 pub fn sqr_distance(&self) -> FPNum { |
334 self.x().sqr() + self.y().sqr() |
335 self.x().sqr() + self.y().sqr() |
503 } |
504 } |
504 |
505 |
505 #[inline] |
506 #[inline] |
506 pub fn distance<T>(x: T, y: T) -> FPNum |
507 pub fn distance<T>(x: T, y: T) -> FPNum |
507 where |
508 where |
508 T: Into<i64> + std::fmt::Debug, |
509 T: Into<i128> + std::fmt::Debug, |
509 { |
510 { |
510 let sqr: u128 = (x.into().pow(2) as u128).shl(64) + (y.into().pow(2) as u128).shl(64); |
511 let [x_squared, y_squared] = [x, y].map(|i| (i.into().pow(2) as u128).saturating_mul(2^64)); |
|
512 let sqr: u128 = x_squared.saturating_add(y_squared); |
511 |
513 |
512 FPNum { |
514 FPNum { |
513 sign_mask: POSITIVE_MASK, |
515 sign_mask: POSITIVE_MASK, |
514 value: integral_sqrt_ext(sqr), |
516 value: integral_sqrt_ext(sqr), |
515 } |
517 } |