noisy_float/
float_impl.rs

1// Copyright 2016-2021 Matthew D. Michelotti
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//   http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use 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 // this accounts for +0.0 and -0.0
125        } 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 // this accounts for +0.0 and -0.0
137        } else {
138            self.value.to_bits()
139        };
140        bits.hash(state);
141    }
142}
143
144// TODO why is `impl<F: Float + Hash, C: FloatChecker<F>> Hash for NoisyFloat<F, C>` considered conflicting?
145
146impl<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}