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