1use crate::{FloatChecker, NoisyFloat};
16use core::{
17 cmp::Ordering,
18 convert::{From, TryFrom},
19 hash::{Hash, Hasher},
20 iter,
21 num::FpCategory,
22 ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign},
23};
24use num_traits::{
25 cast::{FromPrimitive, NumCast, ToPrimitive},
26 identities::{One, Zero},
27 Bounded, Float, FloatConst, Num, Signed,
28};
29
30impl<F: Float, C: FloatChecker<F>> Clone for NoisyFloat<F, C> {
31 #[inline]
32 fn clone(&self) -> Self {
33 Self::unchecked_new_generic(self.value)
34 }
35}
36
37impl<F: Float, C: FloatChecker<F>> Copy for NoisyFloat<F, C> {}
38
39impl<F: Float, C: FloatChecker<F>> AsRef<F> for NoisyFloat<F, C> {
40 fn as_ref(&self) -> &F {
41 &self.value
42 }
43}
44
45impl<F: Float, C: FloatChecker<F>> PartialEq<F> for NoisyFloat<F, C> {
46 #[inline]
47 fn eq(&self, other: &F) -> bool {
48 self.value.eq(&other)
49 }
50}
51
52impl<F: Float, C: FloatChecker<F>> PartialEq for NoisyFloat<F, C> {
53 #[inline]
54 fn eq(&self, other: &Self) -> bool {
55 self.eq(&other.value)
56 }
57}
58
59impl<F: Float, C: FloatChecker<F>> Eq for NoisyFloat<F, C> {}
60
61impl<F: Float, C: FloatChecker<F>> PartialOrd<F> for NoisyFloat<F, C> {
62 #[inline]
63 fn partial_cmp(&self, other: &F) -> Option<Ordering> {
64 self.value.partial_cmp(&other)
65 }
66 #[inline]
67 fn lt(&self, other: &F) -> bool {
68 self.value.lt(&other)
69 }
70 #[inline]
71 fn le(&self, other: &F) -> bool {
72 self.value.le(&other)
73 }
74 #[inline]
75 fn gt(&self, other: &F) -> bool {
76 self.value.gt(&other)
77 }
78 #[inline]
79 fn ge(&self, other: &F) -> bool {
80 self.value.ge(&other)
81 }
82}
83
84impl<F: Float, C: FloatChecker<F>> PartialOrd for NoisyFloat<F, C> {
85 #[inline]
86 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
87 self.value.partial_cmp(&other.value)
88 }
89 #[inline]
90 fn lt(&self, other: &Self) -> bool {
91 self.lt(&other.value)
92 }
93 #[inline]
94 fn le(&self, other: &Self) -> bool {
95 self.le(&other.value)
96 }
97 #[inline]
98 fn gt(&self, other: &Self) -> bool {
99 self.gt(&other.value)
100 }
101 #[inline]
102 fn ge(&self, other: &Self) -> bool {
103 self.ge(&other.value)
104 }
105}
106
107impl<F: Float, C: FloatChecker<F>> Ord for NoisyFloat<F, C> {
108 #[inline]
109 fn cmp(&self, other: &Self) -> Ordering {
110 if self.value < other.value {
111 Ordering::Less
112 } else if self.value == other.value {
113 Ordering::Equal
114 } else {
115 Ordering::Greater
116 }
117 }
118}
119
120impl<C: FloatChecker<f32>> Hash for NoisyFloat<f32, C> {
121 #[inline]
122 fn hash<H: Hasher>(&self, state: &mut H) {
123 let bits = if self.value == 0.0 {
124 0 } else {
126 self.value.to_bits()
127 };
128 bits.hash(state);
129 }
130}
131
132impl<C: FloatChecker<f64>> Hash for NoisyFloat<f64, C> {
133 #[inline]
134 fn hash<H: Hasher>(&self, state: &mut H) {
135 let bits = if self.value == 0.0 {
136 0 } else {
138 self.value.to_bits()
139 };
140 bits.hash(state);
141 }
142}
143
144impl<F: Float, C: FloatChecker<F>> Add<F> for NoisyFloat<F, C> {
147 type Output = Self;
148 #[inline]
149 #[track_caller]
150 fn add(self, rhs: F) -> Self {
151 Self::new(self.value.add(rhs))
152 }
153}
154
155impl<'a, F: Float, C: FloatChecker<F>> Add<&'a F> for NoisyFloat<F, C> {
156 type Output = Self;
157 #[inline]
158 #[track_caller]
159 fn add(self, rhs: &'a F) -> Self {
160 Self::new(self.value.add(*rhs))
161 }
162}
163
164impl<F: Float, C: FloatChecker<F>> Add for NoisyFloat<F, C> {
165 type Output = Self;
166 #[inline]
167 #[track_caller]
168 fn add(self, rhs: Self) -> Self {
169 self.add(rhs.value)
170 }
171}
172
173impl<'a, F: Float, C: FloatChecker<F>> Add<&'a Self> for NoisyFloat<F, C> {
174 type Output = Self;
175 #[inline]
176 #[track_caller]
177 fn add(self, rhs: &'a Self) -> Self {
178 self.add(rhs.value)
179 }
180}
181
182impl<F: Float, C: FloatChecker<F>> Sub<F> for NoisyFloat<F, C> {
183 type Output = Self;
184 #[inline]
185 #[track_caller]
186 fn sub(self, rhs: F) -> Self {
187 Self::new(self.value.sub(rhs))
188 }
189}
190
191impl<'a, F: Float, C: FloatChecker<F>> Sub<&'a F> for NoisyFloat<F, C> {
192 type Output = Self;
193 #[inline]
194 #[track_caller]
195 fn sub(self, rhs: &'a F) -> Self {
196 Self::new(self.value.sub(*rhs))
197 }
198}
199
200impl<F: Float, C: FloatChecker<F>> Sub for NoisyFloat<F, C> {
201 type Output = Self;
202 #[inline]
203 #[track_caller]
204 fn sub(self, rhs: Self) -> Self {
205 self.sub(rhs.value)
206 }
207}
208
209impl<'a, F: Float, C: FloatChecker<F>> Sub<&'a Self> for NoisyFloat<F, C> {
210 type Output = Self;
211 #[inline]
212 #[track_caller]
213 fn sub(self, rhs: &'a Self) -> Self {
214 self.sub(rhs.value)
215 }
216}
217
218impl<F: Float, C: FloatChecker<F>> Mul<F> for NoisyFloat<F, C> {
219 type Output = Self;
220 #[inline]
221 #[track_caller]
222 fn mul(self, rhs: F) -> Self {
223 Self::new(self.value.mul(rhs))
224 }
225}
226
227impl<'a, F: Float, C: FloatChecker<F>> Mul<&'a F> for NoisyFloat<F, C> {
228 type Output = Self;
229 #[inline]
230 #[track_caller]
231 fn mul(self, rhs: &'a F) -> Self {
232 Self::new(self.value.mul(*rhs))
233 }
234}
235
236impl<F: Float, C: FloatChecker<F>> Mul for NoisyFloat<F, C> {
237 type Output = Self;
238 #[inline]
239 #[track_caller]
240 fn mul(self, rhs: Self) -> Self {
241 self.mul(rhs.value)
242 }
243}
244
245impl<'a, F: Float, C: FloatChecker<F>> Mul<&'a Self> for NoisyFloat<F, C> {
246 type Output = Self;
247 #[inline]
248 #[track_caller]
249 fn mul(self, rhs: &'a Self) -> Self {
250 self.mul(rhs.value)
251 }
252}
253
254impl<F: Float, C: FloatChecker<F>> Div<F> for NoisyFloat<F, C> {
255 type Output = Self;
256 #[inline]
257 #[track_caller]
258 fn div(self, rhs: F) -> Self {
259 Self::new(self.value.div(rhs))
260 }
261}
262
263impl<'a, F: Float, C: FloatChecker<F>> Div<&'a F> for NoisyFloat<F, C> {
264 type Output = Self;
265 #[inline]
266 #[track_caller]
267 fn div(self, rhs: &'a F) -> Self {
268 Self::new(self.value.div(*rhs))
269 }
270}
271
272impl<F: Float, C: FloatChecker<F>> Div for NoisyFloat<F, C> {
273 type Output = Self;
274 #[inline]
275 #[track_caller]
276 fn div(self, rhs: Self) -> Self {
277 self.div(rhs.value)
278 }
279}
280
281impl<'a, F: Float, C: FloatChecker<F>> Div<&'a Self> for NoisyFloat<F, C> {
282 type Output = Self;
283 #[inline]
284 #[track_caller]
285 fn div(self, rhs: &'a Self) -> Self {
286 self.div(rhs.value)
287 }
288}
289
290impl<F: Float, C: FloatChecker<F>> Rem<F> for NoisyFloat<F, C> {
291 type Output = Self;
292 #[inline]
293 #[track_caller]
294 fn rem(self, rhs: F) -> Self {
295 Self::new(self.value.rem(rhs))
296 }
297}
298
299impl<'a, F: Float, C: FloatChecker<F>> Rem<&'a F> for NoisyFloat<F, C> {
300 type Output = Self;
301 #[inline]
302 #[track_caller]
303 fn rem(self, rhs: &'a F) -> Self {
304 Self::new(self.value.rem(*rhs))
305 }
306}
307
308impl<F: Float, C: FloatChecker<F>> Rem for NoisyFloat<F, C> {
309 type Output = Self;
310 #[inline]
311 #[track_caller]
312 fn rem(self, rhs: Self) -> Self {
313 self.rem(rhs.value)
314 }
315}
316
317impl<'a, F: Float, C: FloatChecker<F>> Rem<&'a Self> for NoisyFloat<F, C> {
318 type Output = Self;
319 #[inline]
320 #[track_caller]
321 fn rem(self, rhs: &'a Self) -> Self {
322 self.rem(rhs.value)
323 }
324}
325
326impl<F: Float + AddAssign, C: FloatChecker<F>> AddAssign<F> for NoisyFloat<F, C> {
327 #[inline]
328 #[track_caller]
329 fn add_assign(&mut self, rhs: F) {
330 self.value.add_assign(rhs);
331 C::assert(self.value);
332 }
333}
334
335impl<'a, F: Float + AddAssign, C: FloatChecker<F>> AddAssign<&'a F> for NoisyFloat<F, C> {
336 #[inline]
337 #[track_caller]
338 fn add_assign(&mut self, rhs: &'a F) {
339 self.value.add_assign(*rhs);
340 C::assert(self.value);
341 }
342}
343
344impl<F: Float + AddAssign, C: FloatChecker<F>> AddAssign for NoisyFloat<F, C> {
345 #[inline]
346 #[track_caller]
347 fn add_assign(&mut self, rhs: Self) {
348 self.add_assign(rhs.value);
349 }
350}
351
352impl<'a, F: Float + AddAssign, C: FloatChecker<F>> AddAssign<&'a Self> for NoisyFloat<F, C> {
353 #[inline]
354 #[track_caller]
355 fn add_assign(&mut self, rhs: &'a Self) {
356 self.add_assign(rhs.value);
357 }
358}
359
360impl<F: Float + SubAssign, C: FloatChecker<F>> SubAssign<F> for NoisyFloat<F, C> {
361 #[inline]
362 #[track_caller]
363 fn sub_assign(&mut self, rhs: F) {
364 self.value.sub_assign(rhs);
365 C::assert(self.value);
366 }
367}
368
369impl<'a, F: Float + SubAssign, C: FloatChecker<F>> SubAssign<&'a F> for NoisyFloat<F, C> {
370 #[inline]
371 #[track_caller]
372 fn sub_assign(&mut self, rhs: &'a F) {
373 self.value.sub_assign(*rhs);
374 C::assert(self.value);
375 }
376}
377
378impl<F: Float + SubAssign, C: FloatChecker<F>> SubAssign for NoisyFloat<F, C> {
379 #[inline]
380 #[track_caller]
381 fn sub_assign(&mut self, rhs: Self) {
382 self.sub_assign(rhs.value);
383 }
384}
385
386impl<'a, F: Float + SubAssign, C: FloatChecker<F>> SubAssign<&'a Self> for NoisyFloat<F, C> {
387 #[inline]
388 #[track_caller]
389 fn sub_assign(&mut self, rhs: &'a Self) {
390 self.sub_assign(rhs.value);
391 }
392}
393
394impl<F: Float + MulAssign, C: FloatChecker<F>> MulAssign<F> for NoisyFloat<F, C> {
395 #[inline]
396 #[track_caller]
397 fn mul_assign(&mut self, rhs: F) {
398 self.value.mul_assign(rhs);
399 C::assert(self.value);
400 }
401}
402
403impl<'a, F: Float + MulAssign, C: FloatChecker<F>> MulAssign<&'a F> for NoisyFloat<F, C> {
404 #[inline]
405 #[track_caller]
406 fn mul_assign(&mut self, rhs: &'a F) {
407 self.value.mul_assign(*rhs);
408 C::assert(self.value);
409 }
410}
411
412impl<F: Float + MulAssign, C: FloatChecker<F>> MulAssign for NoisyFloat<F, C> {
413 #[inline]
414 #[track_caller]
415 fn mul_assign(&mut self, rhs: Self) {
416 self.mul_assign(rhs.value);
417 }
418}
419
420impl<'a, F: Float + MulAssign, C: FloatChecker<F>> MulAssign<&'a Self> for NoisyFloat<F, C> {
421 #[inline]
422 #[track_caller]
423 fn mul_assign(&mut self, rhs: &'a Self) {
424 self.mul_assign(rhs.value);
425 }
426}
427
428impl<F: Float + DivAssign, C: FloatChecker<F>> DivAssign<F> for NoisyFloat<F, C> {
429 #[inline]
430 #[track_caller]
431 fn div_assign(&mut self, rhs: F) {
432 self.value.div_assign(rhs);
433 C::assert(self.value);
434 }
435}
436
437impl<'a, F: Float + DivAssign, C: FloatChecker<F>> DivAssign<&'a F> for NoisyFloat<F, C> {
438 #[inline]
439 #[track_caller]
440 fn div_assign(&mut self, rhs: &'a F) {
441 self.value.div_assign(*rhs);
442 C::assert(self.value);
443 }
444}
445
446impl<F: Float + DivAssign, C: FloatChecker<F>> DivAssign for NoisyFloat<F, C> {
447 #[inline]
448 #[track_caller]
449 fn div_assign(&mut self, rhs: Self) {
450 self.div_assign(rhs.value);
451 }
452}
453
454impl<'a, F: Float + DivAssign, C: FloatChecker<F>> DivAssign<&'a Self> for NoisyFloat<F, C> {
455 #[inline]
456 #[track_caller]
457 fn div_assign(&mut self, rhs: &'a Self) {
458 self.div_assign(rhs.value);
459 }
460}
461
462impl<F: Float + RemAssign, C: FloatChecker<F>> RemAssign<F> for NoisyFloat<F, C> {
463 #[inline]
464 #[track_caller]
465 fn rem_assign(&mut self, rhs: F) {
466 self.value.rem_assign(rhs);
467 C::assert(self.value);
468 }
469}
470
471impl<'a, F: Float + RemAssign, C: FloatChecker<F>> RemAssign<&'a F> for NoisyFloat<F, C> {
472 #[inline]
473 #[track_caller]
474 fn rem_assign(&mut self, rhs: &'a F) {
475 self.value.rem_assign(*rhs);
476 C::assert(self.value);
477 }
478}
479
480impl<F: Float + RemAssign, C: FloatChecker<F>> RemAssign for NoisyFloat<F, C> {
481 #[inline]
482 #[track_caller]
483 fn rem_assign(&mut self, rhs: Self) {
484 self.rem_assign(rhs.value);
485 }
486}
487
488impl<'a, F: Float + RemAssign, C: FloatChecker<F>> RemAssign<&'a Self> for NoisyFloat<F, C> {
489 #[inline]
490 #[track_caller]
491 fn rem_assign(&mut self, rhs: &'a Self) {
492 self.rem_assign(rhs.value);
493 }
494}
495
496impl<F: Float, C: FloatChecker<F>> Neg for NoisyFloat<F, C> {
497 type Output = Self;
498 #[inline]
499 #[track_caller]
500 fn neg(self) -> Self {
501 Self::new(self.value.neg())
502 }
503}
504
505impl<'a, F: Float, C: FloatChecker<F>> Neg for &'a NoisyFloat<F, C> {
506 type Output = NoisyFloat<F, C>;
507 #[inline]
508 #[track_caller]
509 fn neg(self) -> Self::Output {
510 Self::Output::neg(*self)
511 }
512}
513
514impl<F: Float, C: FloatChecker<F>> Zero for NoisyFloat<F, C> {
515 #[inline]
516 #[track_caller]
517 fn zero() -> Self {
518 Self::new(F::zero())
519 }
520 #[inline]
521 #[track_caller]
522 fn is_zero(&self) -> bool {
523 self.value.is_zero()
524 }
525}
526
527impl<F: Float, C: FloatChecker<F>> One for NoisyFloat<F, C> {
528 #[inline]
529 #[track_caller]
530 fn one() -> Self {
531 Self::new(F::one())
532 }
533}
534
535impl<F: Float, C: FloatChecker<F>> Num for NoisyFloat<F, C> {
536 type FromStrRadixErr = F::FromStrRadixErr;
537 #[inline]
538 #[track_caller]
539 fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
540 F::from_str_radix(str, radix).map(|v| Self::new(v))
541 }
542}
543
544impl<F: Float, C: FloatChecker<F>> ToPrimitive for NoisyFloat<F, C> {
545 #[inline]
546 fn to_i64(&self) -> Option<i64> {
547 self.value.to_i64()
548 }
549 #[inline]
550 fn to_u64(&self) -> Option<u64> {
551 self.value.to_u64()
552 }
553 #[inline]
554 fn to_isize(&self) -> Option<isize> {
555 self.value.to_isize()
556 }
557 #[inline]
558 fn to_i8(&self) -> Option<i8> {
559 self.value.to_i8()
560 }
561 #[inline]
562 fn to_i16(&self) -> Option<i16> {
563 self.value.to_i16()
564 }
565 #[inline]
566 fn to_i32(&self) -> Option<i32> {
567 self.value.to_i32()
568 }
569 #[inline]
570 fn to_usize(&self) -> Option<usize> {
571 self.value.to_usize()
572 }
573 #[inline]
574 fn to_u8(&self) -> Option<u8> {
575 self.value.to_u8()
576 }
577 #[inline]
578 fn to_u16(&self) -> Option<u16> {
579 self.value.to_u16()
580 }
581 #[inline]
582 fn to_u32(&self) -> Option<u32> {
583 self.value.to_u32()
584 }
585 #[inline]
586 fn to_f32(&self) -> Option<f32> {
587 self.value.to_f32()
588 }
589 #[inline]
590 fn to_f64(&self) -> Option<f64> {
591 self.value.to_f64()
592 }
593}
594
595impl<F: Float + FromPrimitive, C: FloatChecker<F>> FromPrimitive for NoisyFloat<F, C> {
596 #[inline]
597 fn from_isize(n: isize) -> Option<Self> {
598 Self::try_new(F::from_isize(n)?)
599 }
600 #[inline]
601 fn from_i8(n: i8) -> Option<Self> {
602 Self::try_new(F::from_i8(n)?)
603 }
604 #[inline]
605 fn from_i16(n: i16) -> Option<Self> {
606 Self::try_new(F::from_i16(n)?)
607 }
608 #[inline]
609 fn from_i32(n: i32) -> Option<Self> {
610 Self::try_new(F::from_i32(n)?)
611 }
612 #[inline]
613 fn from_i64(n: i64) -> Option<Self> {
614 Self::try_new(F::from_i64(n)?)
615 }
616 #[inline]
617 fn from_i128(n: i128) -> Option<Self> {
618 Self::try_new(F::from_i128(n)?)
619 }
620 #[inline]
621 fn from_usize(n: usize) -> Option<Self> {
622 Self::try_new(F::from_usize(n)?)
623 }
624 #[inline]
625 fn from_u8(n: u8) -> Option<Self> {
626 Self::try_new(F::from_u8(n)?)
627 }
628 #[inline]
629 fn from_u16(n: u16) -> Option<Self> {
630 Self::try_new(F::from_u16(n)?)
631 }
632 #[inline]
633 fn from_u32(n: u32) -> Option<Self> {
634 Self::try_new(F::from_u32(n)?)
635 }
636 #[inline]
637 fn from_u64(n: u64) -> Option<Self> {
638 Self::try_new(F::from_u64(n)?)
639 }
640 #[inline]
641 fn from_u128(n: u128) -> Option<Self> {
642 Self::try_new(F::from_u128(n)?)
643 }
644 #[inline]
645 fn from_f32(n: f32) -> Option<Self> {
646 Self::try_new(F::from_f32(n)?)
647 }
648 #[inline]
649 fn from_f64(n: f64) -> Option<Self> {
650 Self::try_new(F::from_f64(n)?)
651 }
652}
653
654impl<F: Float, C: FloatChecker<F>> NumCast for NoisyFloat<F, C> {
655 #[inline]
656 fn from<T: ToPrimitive>(n: T) -> Option<Self> {
657 F::from(n).and_then(|v| Self::try_new(v))
658 }
659}
660
661impl<C: FloatChecker<f32>> From<NoisyFloat<f32, C>> for f32 {
662 #[inline]
663 fn from(n: NoisyFloat<f32, C>) -> Self {
664 n.value
665 }
666}
667
668impl<C: FloatChecker<f64>> From<NoisyFloat<f64, C>> for f64 {
669 #[inline]
670 fn from(n: NoisyFloat<f64, C>) -> Self {
671 n.value
672 }
673}
674
675impl<C: FloatChecker<f32>> From<NoisyFloat<f32, C>> for f64 {
676 #[inline]
677 fn from(n: NoisyFloat<f32, C>) -> Self {
678 n.value as f64
679 }
680}
681
682impl<C: FloatChecker<f64>> TryFrom<f64> for NoisyFloat<f64, C> {
683 type Error = &'static str;
684 #[inline]
685 fn try_from(f: f64) -> Result<Self, Self::Error> {
686 Self::try_new(f).ok_or("illegal value")
687 }
688}
689
690impl<C: FloatChecker<f32>> TryFrom<f32> for NoisyFloat<f32, C> {
691 type Error = &'static str;
692 #[inline]
693 fn try_from(f: f32) -> Result<Self, Self::Error> {
694 Self::try_new(f).ok_or("illegal value")
695 }
696}
697
698impl<F: Float, C: FloatChecker<F>> Float for NoisyFloat<F, C> {
699 #[inline]
700 #[track_caller]
701 fn nan() -> Self {
702 panic!("unexpected NaN")
703 }
704 #[inline]
705 #[track_caller]
706 fn infinity() -> Self {
707 Self::new(F::infinity())
708 }
709 #[inline]
710 #[track_caller]
711 fn neg_infinity() -> Self {
712 Self::new(F::neg_infinity())
713 }
714 #[inline]
715 #[track_caller]
716 fn neg_zero() -> Self {
717 Self::new(F::neg_zero())
718 }
719 #[inline]
720 #[track_caller]
721 fn min_value() -> Self {
722 Self::new(F::min_value())
723 }
724 #[inline]
725 #[track_caller]
726 fn min_positive_value() -> Self {
727 Self::new(F::min_positive_value())
728 }
729 #[inline]
730 #[track_caller]
731 fn max_value() -> Self {
732 Self::new(F::max_value())
733 }
734 #[inline]
735 fn is_nan(self) -> bool {
736 self.value.is_nan()
737 }
738 #[inline]
739 fn is_infinite(self) -> bool {
740 self.value.is_infinite()
741 }
742 #[inline]
743 fn is_finite(self) -> bool {
744 self.value.is_finite()
745 }
746 #[inline]
747 fn is_normal(self) -> bool {
748 self.value.is_normal()
749 }
750 #[inline]
751 fn classify(self) -> FpCategory {
752 self.value.classify()
753 }
754 #[inline]
755 #[track_caller]
756 fn floor(self) -> Self {
757 Self::new(self.value.floor())
758 }
759 #[inline]
760 #[track_caller]
761 fn ceil(self) -> Self {
762 Self::new(self.value.ceil())
763 }
764 #[inline]
765 #[track_caller]
766 fn round(self) -> Self {
767 Self::new(self.value.round())
768 }
769 #[inline]
770 #[track_caller]
771 fn trunc(self) -> Self {
772 Self::new(self.value.trunc())
773 }
774 #[inline]
775 #[track_caller]
776 fn fract(self) -> Self {
777 Self::new(self.value.fract())
778 }
779 #[inline]
780 #[track_caller]
781 fn abs(self) -> Self {
782 Self::new(self.value.abs())
783 }
784 #[inline]
785 #[track_caller]
786 fn signum(self) -> Self {
787 Self::new(self.value.signum())
788 }
789 #[inline]
790 #[track_caller]
791 fn is_sign_positive(self) -> bool {
792 self.value.is_sign_positive()
793 }
794 #[inline]
795 #[track_caller]
796 fn is_sign_negative(self) -> bool {
797 self.value.is_sign_negative()
798 }
799 #[inline]
800 #[track_caller]
801 fn mul_add(self, a: Self, b: Self) -> Self {
802 Self::new(self.value.mul_add(a.value, b.value))
803 }
804 #[inline]
805 #[track_caller]
806 fn recip(self) -> Self {
807 Self::new(self.value.recip())
808 }
809 #[inline]
810 #[track_caller]
811 fn powi(self, n: i32) -> Self {
812 Self::new(self.value.powi(n))
813 }
814 #[inline]
815 #[track_caller]
816 fn powf(self, n: Self) -> Self {
817 Self::new(self.value.powf(n.value))
818 }
819 #[inline]
820 #[track_caller]
821 fn sqrt(self) -> Self {
822 Self::new(self.value.sqrt())
823 }
824 #[inline]
825 #[track_caller]
826 fn exp(self) -> Self {
827 Self::new(self.value.exp())
828 }
829 #[inline]
830 #[track_caller]
831 fn exp2(self) -> Self {
832 Self::new(self.value.exp2())
833 }
834 #[inline]
835 #[track_caller]
836 fn ln(self) -> Self {
837 Self::new(self.value.ln())
838 }
839 #[inline]
840 #[track_caller]
841 fn log(self, base: Self) -> Self {
842 Self::new(self.value.log(base.value))
843 }
844 #[inline]
845 #[track_caller]
846 fn log2(self) -> Self {
847 Self::new(self.value.log2())
848 }
849 #[inline]
850 #[track_caller]
851 fn log10(self) -> Self {
852 Self::new(self.value.log10())
853 }
854 #[inline]
855 #[track_caller]
856 fn max(self, other: Self) -> Self {
857 Self::new(self.value.max(other.value))
858 }
859 #[inline]
860 #[track_caller]
861 fn min(self, other: Self) -> Self {
862 Self::new(self.value.min(other.value))
863 }
864 #[inline]
865 #[track_caller]
866 fn abs_sub(self, other: Self) -> Self {
867 Self::new(self.value.abs_sub(other.value))
868 }
869 #[inline]
870 #[track_caller]
871 fn cbrt(self) -> Self {
872 Self::new(self.value.cbrt())
873 }
874 #[inline]
875 #[track_caller]
876 fn hypot(self, other: Self) -> Self {
877 Self::new(self.value.hypot(other.value))
878 }
879 #[inline]
880 #[track_caller]
881 fn sin(self) -> Self {
882 Self::new(self.value.sin())
883 }
884 #[inline]
885 #[track_caller]
886 fn cos(self) -> Self {
887 Self::new(self.value.cos())
888 }
889 #[inline]
890 #[track_caller]
891 fn tan(self) -> Self {
892 Self::new(self.value.tan())
893 }
894 #[inline]
895 #[track_caller]
896 fn asin(self) -> Self {
897 Self::new(self.value.asin())
898 }
899 #[inline]
900 #[track_caller]
901 fn acos(self) -> Self {
902 Self::new(self.value.acos())
903 }
904 #[inline]
905 #[track_caller]
906 fn atan(self) -> Self {
907 Self::new(self.value.atan())
908 }
909 #[inline]
910 #[track_caller]
911 fn atan2(self, other: Self) -> Self {
912 Self::new(self.value.atan2(other.value))
913 }
914 #[inline]
915 #[track_caller]
916 fn sin_cos(self) -> (Self, Self) {
917 let (a, b) = self.value.sin_cos();
918 (Self::new(a), Self::new(b))
919 }
920 #[inline]
921 #[track_caller]
922 fn exp_m1(self) -> Self {
923 Self::new(self.value.exp_m1())
924 }
925 #[inline]
926 #[track_caller]
927 fn ln_1p(self) -> Self {
928 Self::new(self.value.ln_1p())
929 }
930 #[inline]
931 #[track_caller]
932 fn sinh(self) -> Self {
933 Self::new(self.value.sinh())
934 }
935 #[inline]
936 #[track_caller]
937 fn cosh(self) -> Self {
938 Self::new(self.value.cosh())
939 }
940 #[inline]
941 #[track_caller]
942 fn tanh(self) -> Self {
943 Self::new(self.value.tanh())
944 }
945 #[inline]
946 #[track_caller]
947 fn asinh(self) -> Self {
948 Self::new(self.value.asinh())
949 }
950 #[inline]
951 #[track_caller]
952 fn acosh(self) -> Self {
953 Self::new(self.value.acosh())
954 }
955 #[inline]
956 #[track_caller]
957 fn atanh(self) -> Self {
958 Self::new(self.value.atanh())
959 }
960 #[inline]
961 fn integer_decode(self) -> (u64, i16, i8) {
962 self.value.integer_decode()
963 }
964 #[inline]
965 #[track_caller]
966 fn epsilon() -> Self {
967 Self::new(F::epsilon())
968 }
969 #[inline]
970 #[track_caller]
971 fn to_degrees(self) -> Self {
972 Self::new(self.value.to_degrees())
973 }
974 #[inline]
975 #[track_caller]
976 fn to_radians(self) -> Self {
977 Self::new(self.value.to_radians())
978 }
979}
980
981impl<F: Float + FloatConst, C: FloatChecker<F>> FloatConst for NoisyFloat<F, C> {
982 #[inline]
983 #[track_caller]
984 fn E() -> Self {
985 Self::new(F::E())
986 }
987 #[inline]
988 #[track_caller]
989 fn FRAC_1_PI() -> Self {
990 Self::new(F::FRAC_1_PI())
991 }
992 #[inline]
993 #[track_caller]
994 fn FRAC_1_SQRT_2() -> Self {
995 Self::new(F::FRAC_1_SQRT_2())
996 }
997 #[inline]
998 #[track_caller]
999 fn FRAC_2_PI() -> Self {
1000 Self::new(F::FRAC_2_PI())
1001 }
1002 #[inline]
1003 #[track_caller]
1004 fn FRAC_2_SQRT_PI() -> Self {
1005 Self::new(F::FRAC_2_SQRT_PI())
1006 }
1007 #[inline]
1008 #[track_caller]
1009 fn FRAC_PI_2() -> Self {
1010 Self::new(F::FRAC_PI_2())
1011 }
1012 #[inline]
1013 #[track_caller]
1014 fn FRAC_PI_3() -> Self {
1015 Self::new(F::FRAC_PI_3())
1016 }
1017 #[inline]
1018 #[track_caller]
1019 fn FRAC_PI_4() -> Self {
1020 Self::new(F::FRAC_PI_4())
1021 }
1022 #[inline]
1023 #[track_caller]
1024 fn FRAC_PI_6() -> Self {
1025 Self::new(F::FRAC_PI_6())
1026 }
1027 #[inline]
1028 #[track_caller]
1029 fn FRAC_PI_8() -> Self {
1030 Self::new(F::FRAC_PI_8())
1031 }
1032 #[inline]
1033 #[track_caller]
1034 fn LN_10() -> Self {
1035 Self::new(F::LN_10())
1036 }
1037 #[inline]
1038 #[track_caller]
1039 fn LN_2() -> Self {
1040 Self::new(F::LN_2())
1041 }
1042 #[inline]
1043 #[track_caller]
1044 fn LOG10_E() -> Self {
1045 Self::new(F::LOG10_E())
1046 }
1047 #[inline]
1048 #[track_caller]
1049 fn LOG2_E() -> Self {
1050 Self::new(F::LOG2_E())
1051 }
1052 #[inline]
1053 #[track_caller]
1054 fn PI() -> Self {
1055 Self::new(F::PI())
1056 }
1057 #[inline]
1058 #[track_caller]
1059 fn SQRT_2() -> Self {
1060 Self::new(F::SQRT_2())
1061 }
1062}
1063
1064impl<F: Float + Signed, C: FloatChecker<F>> Signed for NoisyFloat<F, C> {
1065 #[inline]
1066 #[track_caller]
1067 fn abs(&self) -> Self {
1068 Self::new(self.value.abs())
1069 }
1070 #[inline]
1071 #[track_caller]
1072 fn abs_sub(&self, other: &Self) -> Self {
1073 Self::new(self.value.abs_sub(other.value))
1074 }
1075 #[inline]
1076 #[track_caller]
1077 fn signum(&self) -> Self {
1078 Self::new(self.value.signum())
1079 }
1080 #[inline]
1081 fn is_positive(&self) -> bool {
1082 self.value.is_positive()
1083 }
1084 #[inline]
1085 fn is_negative(&self) -> bool {
1086 self.value.is_negative()
1087 }
1088}
1089
1090impl<F: Float + Bounded, C: FloatChecker<F>> Bounded for NoisyFloat<F, C> {
1091 #[inline]
1092 #[track_caller]
1093 fn min_value() -> Self {
1094 Self::new(Float::min_value())
1095 }
1096 #[inline]
1097 #[track_caller]
1098 fn max_value() -> Self {
1099 Self::new(Float::max_value())
1100 }
1101}
1102
1103impl<F: Float, C: FloatChecker<F>> iter::Sum for NoisyFloat<F, C> {
1104 fn sum<I>(iter: I) -> Self
1105 where
1106 I: Iterator<Item = Self>,
1107 {
1108 Self::new(iter.map(|i| i.raw()).fold(F::zero(), |acc, i| acc + i))
1109 }
1110}
1111
1112impl<'a, F: Float, C: FloatChecker<F>> iter::Sum<&'a Self> for NoisyFloat<F, C> {
1113 fn sum<I>(iter: I) -> Self
1114 where
1115 I: Iterator<Item = &'a Self>,
1116 {
1117 Self::new(iter.map(|i| i.raw()).fold(F::zero(), |acc, i| acc + i))
1118 }
1119}
1120
1121impl<F: Float, C: FloatChecker<F>> iter::Product for NoisyFloat<F, C> {
1122 fn product<I>(iter: I) -> Self
1123 where
1124 I: Iterator<Item = Self>,
1125 {
1126 Self::new(iter.map(|i| i.raw()).fold(F::one(), |acc, i| acc * i))
1127 }
1128}
1129
1130impl<'a, F: Float, C: FloatChecker<F>> iter::Product<&'a Self> for NoisyFloat<F, C> {
1131 fn product<I>(iter: I) -> Self
1132 where
1133 I: Iterator<Item = &'a Self>,
1134 {
1135 Self::new(iter.map(|i| i.raw()).fold(F::one(), |acc, i| acc * i))
1136 }
1137}
1138
1139#[cfg(feature = "approx")]
1140mod approx_impl {
1141 use super::*;
1142 use approx::{AbsDiffEq, RelativeEq, UlpsEq};
1143
1144 impl<F, C> AbsDiffEq<Self> for NoisyFloat<F, C>
1145 where
1146 F: Float + AbsDiffEq<Epsilon = F>,
1147 C: FloatChecker<F>,
1148 {
1149 type Epsilon = NoisyFloat<F, C>;
1150
1151 fn default_epsilon() -> Self::Epsilon {
1152 Self::Epsilon::new(F::default_epsilon())
1153 }
1154
1155 fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
1156 self.raw().abs_diff_eq(&other.raw(), epsilon.raw())
1157 }
1158 }
1159
1160 impl<F, C> RelativeEq<Self> for NoisyFloat<F, C>
1161 where
1162 F: Float + RelativeEq<Epsilon = F>,
1163 C: FloatChecker<F>,
1164 {
1165 fn default_max_relative() -> Self::Epsilon {
1166 Self::new(F::default_max_relative())
1167 }
1168
1169 fn relative_eq(
1170 &self,
1171 other: &Self,
1172 epsilon: Self::Epsilon,
1173 max_relative: Self::Epsilon,
1174 ) -> bool {
1175 self.raw()
1176 .relative_eq(&other.raw(), epsilon.raw(), max_relative.raw())
1177 }
1178 }
1179
1180 impl<F, C> UlpsEq<Self> for NoisyFloat<F, C>
1181 where
1182 F: Float + UlpsEq<Epsilon = F>,
1183 C: FloatChecker<F>,
1184 {
1185 fn default_max_ulps() -> u32 {
1186 F::default_max_ulps()
1187 }
1188
1189 fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
1190 self.raw().ulps_eq(&other.raw(), epsilon.raw(), max_ulps)
1191 }
1192 }
1193}