1use super::*;
2
3pub trait Real: Num + Copy {
5 const PI: Self;
7
8 fn acos(self) -> Self;
12
13 fn asin(self) -> Self;
17
18 fn atan(self) -> Self;
22
23 fn atan2(y: Self, x: Self) -> Self;
30
31 fn ceil(self) -> Self;
33
34 fn cos(self) -> Self;
36
37 fn div_euclid(self, other: Self) -> Self;
42
43 fn exp(self) -> Self;
45
46 fn floor(self) -> Self;
48
49 fn fract(self) -> Self;
51
52 fn ln(self) -> Self;
54
55 fn log(self, base: Self) -> Self;
57
58 fn log10(self) -> Self;
60
61 fn log2(self) -> Self;
63
64 fn powf(self, n: Self) -> Self;
66
67 fn powi(self, n: i32) -> Self;
69
70 fn recip(self) -> Self;
72
73 fn rem_euclid(self, other: Self) -> Self;
84
85 fn round(self) -> Self;
88
89 fn sin(self) -> Self;
91
92 fn sin_cos(self) -> (Self, Self);
95
96 fn sqrt(self) -> Self;
100
101 fn tan(self) -> Self;
103
104 fn from_f32(x: f32) -> Self;
106
107 fn as_f32(self) -> f32;
109}
110
111impl<T: Real> Float for T {
112 const PI: Self = <Self as Real>::PI;
113 fn acos(self) -> Self {
114 Real::acos(self)
115 }
116 fn asin(self) -> Self {
117 Real::asin(self)
118 }
119 fn atan(self) -> Self {
120 Real::atan(self)
121 }
122 fn atan2(y: Self, x: Self) -> Self {
123 Real::atan2(y, x)
124 }
125 fn ceil(self) -> Self {
126 Real::ceil(self)
127 }
128 fn cos(self) -> Self {
129 Real::cos(self)
130 }
131 fn div_euclid(self, other: Self) -> Self {
132 Real::div_euclid(self, other)
133 }
134 fn exp(self) -> Self {
135 Real::exp(self)
136 }
137 fn floor(self) -> Self {
138 Real::floor(self)
139 }
140 fn fract(self) -> Self {
141 Real::fract(self)
142 }
143 fn ln(self) -> Self {
144 Real::ln(self)
145 }
146 fn log(self, base: Self) -> Self {
147 Real::log(self, base)
148 }
149 fn log10(self) -> Self {
150 Real::log10(self)
151 }
152 fn log2(self) -> Self {
153 Real::log2(self)
154 }
155 fn powf(self, n: Self) -> Self {
156 Real::powf(self, n)
157 }
158 fn powi(self, n: i32) -> Self {
159 Real::powi(self, n)
160 }
161 fn recip(self) -> Self {
162 Real::recip(self)
163 }
164 fn rem_euclid(self, other: Self) -> Self {
165 Real::rem_euclid(self, other)
166 }
167 fn round(self) -> Self {
168 Real::round(self)
169 }
170 fn sin(self) -> Self {
171 Real::sin(self)
172 }
173 fn sin_cos(self) -> (Self, Self) {
174 Real::sin_cos(self)
175 }
176 fn sqrt(self) -> Self {
177 Real::sqrt(self)
178 }
179 fn tan(self) -> Self {
180 Real::tan(self)
181 }
182 fn from_f32(x: f32) -> Self {
183 Real::from_f32(x)
184 }
185 fn as_f32(self) -> f32 {
186 Real::as_f32(self)
187 }
188 fn is_finite(self) -> bool {
189 true
190 }
191}
192
193#[derive(Copy, Clone, PartialEq, serde::Serialize)]
195#[serde(transparent)]
196#[repr(transparent)]
197pub struct RealImpl<T: Float>(T);
198
199macro_rules! impl_for {
200 ($t:ty) => {
201 impl<'de> serde::Deserialize<'de> for RealImpl<$t> {
202 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
203 where
204 D: serde::Deserializer<'de>,
205 {
206 <$t as serde::Deserialize>::deserialize(deserializer)?
207 .try_into()
208 .map_err(serde::de::Error::custom)
209 }
210 }
211 impl TryFrom<$t> for RealImpl<$t> {
212 type Error = &'static str;
213 fn try_from(value: $t) -> Result<Self, Self::Error> {
214 if value.is_finite() {
215 Ok(Self::new_unchecked(value))
216 } else {
217 Err("Value must be finite")
218 }
219 }
220 }
221 };
222}
223
224#[test]
225fn test_real_ron() {
226 let s = ron::to_string(&r32(1.5)).unwrap();
227 assert_eq!(ron::from_str(&s), Ok(r32(1.5)));
228}
229
230#[test]
231fn test_real_bincode() {
232 let data = bincode::serialize(&f32::NAN).unwrap();
233 assert!(bincode::deserialize::<R32>(&data).is_err());
234 let data = bincode::serialize(&1.3f32).unwrap();
235 assert_eq!(bincode::deserialize::<R32>(&data).unwrap(), r32(1.3));
236}
237
238impl_for!(f32);
239impl_for!(f64);
240
241impl<T: Float> std::fmt::Debug for RealImpl<T> {
242 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
243 <T as std::fmt::Debug>::fmt(&self.0, fmt)
244 }
245}
246
247impl<T: Float> std::fmt::Display for RealImpl<T> {
248 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
249 <T as std::fmt::Display>::fmt(&self.0, fmt)
250 }
251}
252
253impl<T: Float> RealImpl<T> {
254 pub fn new(value: T) -> Self {
256 assert!(value.is_finite());
257 Self(value)
258 }
259
260 pub fn new_unchecked(value: T) -> Self {
262 Self(value)
263 }
264
265 pub fn raw(self) -> T {
267 self.0
268 }
269}
270
271impl<T: Float> Eq for RealImpl<T> {}
272
273impl<T: Float> PartialOrd for RealImpl<T> {
274 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
275 Some(self.cmp(other))
276 }
277}
278
279impl<T: Float> Ord for RealImpl<T> {
280 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
281 self.0.partial_cmp(&other.0).unwrap()
282 }
283}
284
285macro_rules! impl_op {
286 ($($op:ident: $fn:ident,)*) => {
287 $(
288 impl<T: Float> std::ops::$op for RealImpl<T> {
289 type Output = Self;
290 fn $fn(self, rhs: Self) -> Self {
291 Self::new(self.0 .$fn(rhs.0))
292 }
293 }
294 )*
295 };
296}
297macro_rules! impl_op_assign {
298 ($($op:ident: $fn:ident,)*) => {
299 $(
300 impl<T: Float> std::ops::$op for RealImpl<T> {
301 fn $fn(&mut self, rhs: Self) {
302 self.0 .$fn(rhs.0);
303 }
304 }
305 )*
306 };
307}
308
309impl_op! {
310 Add: add,
311 Sub: sub,
312 Mul: mul,
313 Div: div,
314}
315
316impl_op_assign! {
317 AddAssign: add_assign,
318 SubAssign: sub_assign,
319 MulAssign: mul_assign,
320 DivAssign: div_assign,
321}
322
323impl<T: Float> std::ops::Neg for RealImpl<T> {
324 type Output = Self;
325 fn neg(self) -> Self {
326 Self::new(-self.0)
327 }
328}
329
330impl<T: Float> UNum for RealImpl<T> {
331 const ZERO: Self = Self(T::ZERO);
332 const ONE: Self = Self(T::ONE);
333}
334
335impl<T: Float> Num for RealImpl<T> {
336 fn signum(self) -> Self {
337 Self::new(<T as Num>::signum(self.0))
338 }
339}
340
341pub struct UniformReal<T: rand::distributions::uniform::SampleUniform>(T::Sampler);
343
344impl<T: Float + rand::distributions::uniform::SampleUniform>
345 rand::distributions::uniform::UniformSampler for UniformReal<T>
346{
347 type X = RealImpl<T>;
348
349 fn new<B1, B2>(low: B1, high: B2) -> Self
350 where
351 B1: rand::distributions::uniform::SampleBorrow<Self::X> + Sized,
352 B2: rand::distributions::uniform::SampleBorrow<Self::X> + Sized,
353 {
354 Self(T::Sampler::new(low.borrow().0, high.borrow().0))
355 }
356
357 fn new_inclusive<B1, B2>(low: B1, high: B2) -> Self
358 where
359 B1: rand::distributions::uniform::SampleBorrow<Self::X> + Sized,
360 B2: rand::distributions::uniform::SampleBorrow<Self::X> + Sized,
361 {
362 Self(T::Sampler::new_inclusive(low.borrow().0, high.borrow().0))
363 }
364
365 fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
366 RealImpl(self.0.sample(rng))
367 }
368
369 fn sample_single<R: rand::Rng + ?Sized, B1, B2>(low: B1, high: B2, rng: &mut R) -> Self::X
370 where
371 B1: rand::distributions::uniform::SampleBorrow<Self::X> + Sized,
372 B2: rand::distributions::uniform::SampleBorrow<Self::X> + Sized,
373 {
374 RealImpl(T::Sampler::sample_single(
375 low.borrow().0,
376 high.borrow().0,
377 rng,
378 ))
379 }
380
381 fn sample_single_inclusive<R: rand::Rng + ?Sized, B1, B2>(
382 low: B1,
383 high: B2,
384 rng: &mut R,
385 ) -> Self::X
386 where
387 B1: rand::distributions::uniform::SampleBorrow<Self::X> + Sized,
388 B2: rand::distributions::uniform::SampleBorrow<Self::X> + Sized,
389 {
390 RealImpl(T::Sampler::sample_single_inclusive(
391 low.borrow().0,
392 high.borrow().0,
393 rng,
394 ))
395 }
396}
397
398impl<T: Float + rand::distributions::uniform::SampleUniform>
399 rand::distributions::uniform::SampleUniform for RealImpl<T>
400{
401 type Sampler = UniformReal<T>;
402}
403
404impl<T: Float> Real for RealImpl<T> {
405 const PI: Self = Self(T::PI);
406 fn acos(self) -> Self {
407 Self::new(T::acos(self.0))
408 }
409 fn asin(self) -> Self {
410 Self::new(T::asin(self.0))
411 }
412 fn atan(self) -> Self {
413 Self::new(T::atan(self.0))
414 }
415 fn atan2(y: Self, x: Self) -> Self {
416 Self::new(T::atan2(y.0, x.0))
417 }
418 fn ceil(self) -> Self {
419 Self::new(T::ceil(self.0))
420 }
421 fn cos(self) -> Self {
422 Self::new(T::cos(self.0))
423 }
424 fn div_euclid(self, other: Self) -> Self {
425 Self::new(T::div_euclid(self.0, other.0))
426 }
427 fn exp(self) -> Self {
428 Self::new(T::exp(self.0))
429 }
430 fn floor(self) -> Self {
431 Self::new(T::floor(self.0))
432 }
433 fn fract(self) -> Self {
434 Self::new(T::fract(self.0))
435 }
436 fn ln(self) -> Self {
437 Self::new(T::ln(self.0))
438 }
439 fn log(self, base: Self) -> Self {
440 Self::new(T::log(self.0, base.0))
441 }
442 fn log10(self) -> Self {
443 Self::new(T::log10(self.0))
444 }
445 fn log2(self) -> Self {
446 Self::new(T::log2(self.0))
447 }
448 fn powf(self, n: Self) -> Self {
449 Self::new(T::powf(self.0, n.0))
450 }
451 fn powi(self, n: i32) -> Self {
452 Self::new(T::powi(self.0, n))
453 }
454 fn recip(self) -> Self {
455 Self::new(T::recip(self.0))
456 }
457 fn rem_euclid(self, other: Self) -> Self {
458 Self::new(T::rem_euclid(self.0, other.0))
459 }
460 fn round(self) -> Self {
461 Self::new(T::round(self.0))
462 }
463 fn sin(self) -> Self {
464 Self::new(T::sin(self.0))
465 }
466 fn sin_cos(self) -> (Self, Self) {
467 let (sin, cos) = T::sin_cos(self.0);
468 (Self::new(sin), Self::new(cos))
469 }
470 fn sqrt(self) -> Self {
471 Self::new(T::sqrt(self.0))
472 }
473 fn tan(self) -> Self {
474 Self::new(T::tan(self.0))
475 }
476 fn from_f32(x: f32) -> Self {
477 Self::new(T::from_f32(x))
478 }
479 fn as_f32(self) -> f32 {
480 self.0.as_f32()
481 }
482}
483
484impl<T: Float> RealImpl<T> {
486 pub const PI: Self = <Self as Real>::PI;
488
489 pub fn acos(self) -> Self {
493 <Self as Real>::acos(self)
494 }
495
496 pub fn asin(self) -> Self {
500 <Self as Real>::asin(self)
501 }
502
503 pub fn atan(self) -> Self {
507 <Self as Real>::atan(self)
508 }
509
510 pub fn atan2(y: Self, x: Self) -> Self {
517 <Self as Real>::atan2(y, x)
518 }
519
520 pub fn ceil(self) -> Self {
522 <Self as Real>::ceil(self)
523 }
524
525 pub fn cos(self) -> Self {
527 <Self as Real>::cos(self)
528 }
529
530 pub fn div_euclid(self, other: Self) -> Self {
535 <Self as Real>::div_euclid(self, other)
536 }
537
538 pub fn exp(self) -> Self {
540 <Self as Real>::exp(self)
541 }
542
543 pub fn floor(self) -> Self {
545 <Self as Real>::floor(self)
546 }
547
548 pub fn fract(self) -> Self {
550 <Self as Real>::fract(self)
551 }
552
553 pub fn ln(self) -> Self {
555 <Self as Real>::ln(self)
556 }
557
558 pub fn log(self, base: Self) -> Self {
560 <Self as Real>::log(self, base)
561 }
562
563 pub fn log10(self) -> Self {
565 <Self as Real>::log10(self)
566 }
567
568 pub fn log2(self) -> Self {
570 <Self as Real>::log2(self)
571 }
572
573 pub fn powf(self, n: Self) -> Self {
575 <Self as Real>::powf(self, n)
576 }
577
578 pub fn powi(self, n: i32) -> Self {
580 <Self as Real>::powi(self, n)
581 }
582
583 pub fn recip(self) -> Self {
585 <Self as Real>::recip(self)
586 }
587
588 pub fn rem_euclid(self, other: Self) -> Self {
599 <Self as Real>::rem_euclid(self, other)
600 }
601
602 pub fn round(self) -> Self {
605 <Self as Real>::round(self)
606 }
607
608 pub fn signum(self) -> Self {
614 <Self as Num>::signum(self)
615 }
616
617 pub fn sin(self) -> Self {
619 <Self as Real>::sin(self)
620 }
621
622 pub fn sin_cos(self) -> (Self, Self) {
625 <Self as Real>::sin_cos(self)
626 }
627
628 pub fn sqrt(self) -> Self {
632 <Self as Real>::sqrt(self)
633 }
634
635 pub fn tan(self) -> Self {
637 <Self as Real>::tan(self)
638 }
639
640 pub fn from_f32(x: f32) -> Self {
642 <Self as Real>::from_f32(x)
643 }
644
645 pub fn as_f32(self) -> f32 {
647 <Self as Real>::as_f32(self)
648 }
649}
650
651pub type R32 = RealImpl<f32>;
653
654pub fn r32(value: f32) -> R32 {
656 R32::new(value)
657}
658
659pub type R64 = RealImpl<f64>;
661
662pub fn r64(value: f64) -> R64 {
664 R64::new(value)
665}
666
667#[test]
668fn test_reals() {
669 let a = r64(3.0);
670 let b = r64(2.0);
671 println!("a = {a:?}, b = {b:?}");
672 println!("a + b = {:?}", a + b);
673 println!("a - b = {:?}", a - b);
674 println!("a * b = {:?}", a * b);
675 println!("a / b = {:?}", a / b);
676 println!("sin_cos(a) = {:?}", a.sin_cos());
677
678 let mut arr = [r32(1.0), r32(0.0)];
679 arr.sort();
680
681 let _random = rand::Rng::gen_range(&mut rand::thread_rng(), r32(0.0)..r32(1.0));
682}
683
684#[test]
685#[should_panic]
686fn test_reals_fail() {
687 println!("0 / 0 = {:?}", R64::ZERO / R64::ZERO);
688}