srmfpa/impl/
f64.rs

1//! Functions for [`f64`].
2//!
3//! Notes, they panic when fails to set/reset rounding mode.
4
5use crate::internal::*;
6use crate::RoundingMode;
7use crate::{CielArithmetic, FloorArithmetic, RoundTiesEvenArithmetic, TruncArithmetic};
8use crate::{CielMath, FloorMath, RoundTiesEvenMath, TruncMath};
9use crate::{RoundingArithmetic, RoundingMath};
10
11#[cfg(not(feature = "f64_softfloat"))]
12pub use crate::r#impl::builtin::f64::*;
13#[cfg(feature = "f64_softfloat")]
14pub use crate::r#impl::softfloat::f64::*;
15
16impl_non_round_func_binary_all!(
17    f64, NearestTiesEven, "to nearest, ties to even",
18    round_ties_even_add => round_add,
19    round_ties_even_sub => round_sub,
20    round_ties_even_mul => round_mul,
21    round_ties_even_div => round_div,
22    round_ties_even_mul_add => round_mul_add,
23);
24
25impl_non_round_func_binary_all!(
26    f64, TowardPosInf, "toward +∞",
27    ciel_add => round_add,
28    ciel_sub => round_sub,
29    ciel_mul => round_mul,
30    ciel_div => round_div,
31    ciel_mul_add => round_mul_add,
32);
33
34impl_non_round_func_binary_all!(
35    f64, TowardNegInf, "toward -∞",
36    floor_add => round_add,
37    floor_sub => round_sub,
38    floor_mul => round_mul,
39    floor_div => round_div,
40    floor_mul_add => round_mul_add,
41);
42
43impl_non_round_func_binary_all!(
44    f64, TowardZero, "toward 0",
45    trunc_add => round_add,
46    trunc_sub => round_sub,
47    trunc_mul => round_mul,
48    trunc_div => round_div,
49    trunc_mul_add => round_mul_add,
50);
51
52impl_func_unary!(
53    /// Returns `a.sqrt()` as rounding to nearest, ties to even.
54    ///
55    /// # Safety
56    ///
57    /// Panics when fail to set/rest rounding mode.
58    #[must_use = "method returns a new number and does not mutate the original value"]
59    #[inline]
60    => f64, round_ties_even_sqrt, round_sqrt, NearestTiesEven
61);
62impl_func_unary!(
63    /// Returns `a.sqrt()` as rounding toward +∞.
64    ///
65    /// # Safety
66    ///
67    /// Panics when fail to set/rest rounding mode.
68    #[must_use = "method returns a new number and does not mutate the original value"]
69    #[inline]
70    => f64, ciel_sqrt, round_sqrt, TowardPosInf
71);
72impl_func_unary!(
73    /// Returns `a.sqrt()` as rounding toward -∞.
74    ///
75    /// # Safety
76    ///
77    /// Panics when fail to set/rest rounding mode.
78    #[must_use = "method returns a new number and does not mutate the original value"]
79    #[inline]
80    => f64, floor_sqrt, round_sqrt, TowardNegInf
81);
82impl_func_unary!(
83    /// Returns `a.sqrt()` as rounding toward 0.
84    ///
85    /// # Safety
86    ///
87    /// Panics when fail to set/rest rounding mode.
88    #[must_use = "method returns a new number and does not mutate the original value"]
89    #[inline]
90    => f64, trunc_sqrt, round_sqrt, TowardZero
91);
92
93impl RoundingArithmetic for f64 {
94    type Output = Self;
95
96    impl_round_binary!(round_add);
97    impl_round_binary!(round_sub);
98    impl_round_binary!(round_mul);
99    impl_round_binary!(round_div);
100    impl_round_ternary!(round_mul_add);
101}
102
103impl RoundingMath for f64 {
104    type Output = Self;
105
106    #[must_use = "method returns a new number and does not mutate the original value"]
107    #[inline]
108    fn round_sqrt(self, mode: &RoundingMode) -> Self::Output {
109        round_sqrt(self, mode)
110    }
111}
112
113impl RoundTiesEvenArithmetic for f64 {
114    type Output = Self;
115
116    impl_non_round_binary!(round_ties_even_add);
117    impl_non_round_binary!(round_ties_even_sub);
118    impl_non_round_binary!(round_ties_even_mul);
119    impl_non_round_binary!(round_ties_even_div);
120    impl_non_round_ternary!(round_ties_even_mul_add);
121}
122
123impl RoundTiesEvenMath for f64 {
124    type Output = Self;
125
126    #[must_use = "method returns a new number and does not mutate the original value"]
127    #[inline]
128    fn round_ties_even_sqrt(self) -> Self::Output {
129        round_ties_even_sqrt(self)
130    }
131}
132
133impl CielArithmetic for f64 {
134    type Output = Self;
135
136    impl_non_round_binary!(ciel_add);
137    impl_non_round_binary!(ciel_sub);
138    impl_non_round_binary!(ciel_mul);
139    impl_non_round_binary!(ciel_div);
140    impl_non_round_ternary!(ciel_mul_add);
141}
142
143impl CielMath for f64 {
144    type Output = Self;
145
146    #[must_use = "method returns a new number and does not mutate the original value"]
147    #[inline]
148    fn ciel_sqrt(self) -> Self::Output {
149        ciel_sqrt(self)
150    }
151}
152
153impl FloorArithmetic for f64 {
154    type Output = Self;
155
156    impl_non_round_binary!(floor_add);
157    impl_non_round_binary!(floor_sub);
158    impl_non_round_binary!(floor_mul);
159    impl_non_round_binary!(floor_div);
160    impl_non_round_ternary!(floor_mul_add);
161}
162
163impl FloorMath for f64 {
164    type Output = Self;
165
166    #[must_use = "method returns a new number and does not mutate the original value"]
167    #[inline]
168    fn floor_sqrt(self) -> Self::Output {
169        floor_sqrt(self)
170    }
171}
172
173impl TruncArithmetic for f64 {
174    type Output = Self;
175
176    impl_non_round_binary!(trunc_add);
177    impl_non_round_binary!(trunc_sub);
178    impl_non_round_binary!(trunc_mul);
179    impl_non_round_binary!(trunc_div);
180    impl_non_round_ternary!(trunc_mul_add);
181}
182
183impl TruncMath for f64 {
184    type Output = Self;
185
186    #[must_use = "method returns a new number and does not mutate the original value"]
187    #[inline]
188    fn trunc_sqrt(self) -> Self::Output {
189        trunc_sqrt(self)
190    }
191}
192
193/// accrual test
194#[cfg(test)]
195mod test_fn_arith {
196    use crate::RoundingMode as Mode;
197
198    use super::*;
199
200    #[test]
201    fn test_add() {
202        let (a, b) = (0.1, 0.2);
203        let e: f64 = 0.3;
204        assert_eq!(round_add(a, b, &Mode::NearestTiesEven), e.next_up());
205        assert_eq!(round_add(a, b, &Mode::TowardPosInf), e.next_up());
206        assert_eq!(round_add(a, b, &Mode::TowardNegInf), e);
207        assert_eq!(round_add(a, b, &Mode::TowardZero), e);
208
209        let (a, b) = (-0.1, -0.2);
210        let e: f64 = -0.3;
211        assert_eq!(round_add(a, b, &Mode::NearestTiesEven), e.next_down());
212        assert_eq!(round_add(a, b, &Mode::TowardPosInf), e);
213        assert_eq!(round_add(a, b, &Mode::TowardNegInf), e.next_down());
214        assert_eq!(round_add(a, b, &Mode::TowardZero), e);
215    }
216
217    #[test]
218    fn test_sub() {
219        let (a, b) = (0.3, 0.01);
220        let e: f64 = 0.29;
221        assert_eq!(round_sub(a, b, &Mode::NearestTiesEven), e);
222        assert_eq!(round_sub(a, b, &Mode::TowardPosInf), e.next_up());
223        assert_eq!(round_sub(a, b, &Mode::TowardNegInf), e);
224        assert_eq!(round_sub(a, b, &Mode::TowardZero), e);
225
226        let (a, b) = (-0.3, -0.01);
227        let e: f64 = -0.29;
228        assert_eq!(round_sub(a, b, &Mode::NearestTiesEven), e);
229        assert_eq!(round_sub(a, b, &Mode::TowardPosInf), e);
230        assert_eq!(round_sub(a, b, &Mode::TowardNegInf), e.next_down());
231        assert_eq!(round_sub(a, b, &Mode::TowardZero), e);
232    }
233
234    #[test]
235    fn test_mul() {
236        let (a, b) = (0.3, 0.3);
237        let e: f64 = 0.09;
238        assert_eq!(round_mul(a, b, &Mode::NearestTiesEven), e);
239        assert_eq!(round_mul(a, b, &Mode::TowardPosInf), e);
240        assert_eq!(round_mul(a, b, &Mode::TowardNegInf), e.next_down());
241        assert_eq!(round_mul(a, b, &Mode::TowardZero), e.next_down());
242
243        let (a, b) = (-0.3, 0.3);
244        let e: f64 = -0.09;
245        assert_eq!(round_mul(a, b, &Mode::NearestTiesEven), e);
246        assert_eq!(round_mul(a, b, &Mode::TowardPosInf), e.next_up());
247        assert_eq!(round_mul(a, b, &Mode::TowardNegInf), e);
248        assert_eq!(round_mul(a, b, &Mode::TowardZero), e.next_up());
249    }
250
251    #[test]
252    fn test_div() {
253        let (a, b) = (0.3, 0.2);
254        let e: f64 = 1.5;
255        assert_eq!(round_div(a, b, &Mode::NearestTiesEven), e.next_down());
256        assert_eq!(round_div(a, b, &Mode::TowardPosInf), e);
257        assert_eq!(round_div(a, b, &Mode::TowardNegInf), e.next_down());
258        assert_eq!(round_div(a, b, &Mode::TowardZero), e.next_down());
259
260        let (a, b) = (-0.3, 0.2);
261        let e: f64 = -1.5;
262        assert_eq!(round_div(a, b, &Mode::NearestTiesEven), e.next_up());
263        assert_eq!(round_div(a, b, &Mode::TowardPosInf), e.next_up());
264        assert_eq!(round_div(a, b, &Mode::TowardNegInf), e);
265        assert_eq!(round_div(a, b, &Mode::TowardZero), e.next_up());
266    }
267
268    #[test]
269    fn test_mul_add() {
270        let (a, b, c) = (0.3, 0.2, 0.1);
271        let e: f64 = 0.16;
272        assert_eq!(round_mul_add(a, b, c, &Mode::NearestTiesEven), e);
273        assert_eq!(round_mul_add(a, b, c, &Mode::TowardPosInf), e.next_up());
274        assert_eq!(round_mul_add(a, b, c, &Mode::TowardNegInf), e);
275        assert_eq!(round_mul_add(a, b, c, &Mode::TowardZero), e);
276
277        let (a, b, c) = (-0.3, 0.2, -0.1);
278        let e: f64 = -0.16;
279        assert_eq!(round_mul_add(a, b, c, &Mode::NearestTiesEven), e);
280        assert_eq!(round_mul_add(a, b, c, &Mode::TowardPosInf), e);
281        assert_eq!(round_mul_add(a, b, c, &Mode::TowardNegInf), e.next_down());
282        assert_eq!(round_mul_add(a, b, c, &Mode::TowardZero), e);
283    }
284}
285
286#[cfg(test)]
287mod test_fn_arith_mono {
288    use crate::RoundingMode as Mode;
289
290    use super::*;
291
292    #[test]
293    fn test_add() {
294        let (a, b) = (0.1, 0.2);
295        assert_eq!(
296            round_ties_even_add(a, b),
297            round_add(a, b, &Mode::NearestTiesEven)
298        );
299        assert_eq!(ciel_add(a, b), round_add(a, b, &Mode::TowardPosInf));
300        assert_eq!(floor_add(a, b), round_add(a, b, &Mode::TowardNegInf));
301        assert_eq!(trunc_add(a, b), round_add(a, b, &Mode::TowardZero));
302
303        let (a, b) = (-0.1, -0.2);
304        assert_eq!(
305            round_ties_even_add(a, b),
306            round_add(a, b, &Mode::NearestTiesEven)
307        );
308        assert_eq!(ciel_add(a, b), round_add(a, b, &Mode::TowardPosInf));
309        assert_eq!(floor_add(a, b), round_add(a, b, &Mode::TowardNegInf));
310        assert_eq!(trunc_add(a, b), round_add(a, b, &Mode::TowardZero));
311    }
312
313    #[test]
314    fn test_sub() {
315        let (a, b) = (0.3, 0.01);
316        assert_eq!(
317            round_ties_even_sub(a, b),
318            round_sub(a, b, &Mode::NearestTiesEven)
319        );
320        assert_eq!(ciel_sub(a, b), round_sub(a, b, &Mode::TowardPosInf));
321        assert_eq!(floor_sub(a, b), round_sub(a, b, &Mode::TowardNegInf));
322        assert_eq!(trunc_sub(a, b), round_sub(a, b, &Mode::TowardZero));
323
324        let (a, b) = (-0.3, -0.01);
325        assert_eq!(
326            round_ties_even_sub(a, b),
327            round_sub(a, b, &Mode::NearestTiesEven)
328        );
329        assert_eq!(ciel_sub(a, b), round_sub(a, b, &Mode::TowardPosInf));
330        assert_eq!(floor_sub(a, b), round_sub(a, b, &Mode::TowardNegInf));
331        assert_eq!(trunc_sub(a, b), round_sub(a, b, &Mode::TowardZero));
332    }
333
334    #[test]
335    fn test_mul() {
336        let (a, b) = (0.3, 0.3);
337        assert_eq!(
338            round_ties_even_mul(a, b),
339            round_mul(a, b, &Mode::NearestTiesEven)
340        );
341        assert_eq!(ciel_mul(a, b), round_mul(a, b, &Mode::TowardPosInf));
342        assert_eq!(floor_mul(a, b), round_mul(a, b, &Mode::TowardNegInf));
343        assert_eq!(trunc_mul(a, b), round_mul(a, b, &Mode::TowardZero));
344
345        let (a, b) = (0.3, 0.3);
346        assert_eq!(
347            round_ties_even_mul(a, b),
348            round_mul(a, b, &Mode::NearestTiesEven)
349        );
350        assert_eq!(ciel_mul(a, b), round_mul(a, b, &Mode::TowardPosInf));
351        assert_eq!(floor_mul(a, b), round_mul(a, b, &Mode::TowardNegInf));
352        assert_eq!(trunc_mul(a, b), round_mul(a, b, &Mode::TowardZero));
353    }
354
355    #[test]
356    fn test_div() {
357        let (a, b) = (0.3, 0.2);
358        assert_eq!(
359            round_ties_even_div(a, b),
360            round_div(a, b, &Mode::NearestTiesEven)
361        );
362        assert_eq!(ciel_div(a, b), round_div(a, b, &Mode::TowardPosInf));
363        assert_eq!(floor_div(a, b), round_div(a, b, &Mode::TowardNegInf));
364        assert_eq!(trunc_div(a, b), round_div(a, b, &Mode::TowardZero));
365
366        let (a, b) = (0.3, 0.2);
367        assert_eq!(
368            round_ties_even_div(a, b),
369            round_div(a, b, &Mode::NearestTiesEven)
370        );
371        assert_eq!(ciel_div(a, b), round_div(a, b, &Mode::TowardPosInf));
372        assert_eq!(floor_div(a, b), round_div(a, b, &Mode::TowardNegInf));
373        assert_eq!(trunc_div(a, b), round_div(a, b, &Mode::TowardZero));
374    }
375
376    #[test]
377    fn test_mul_add() {
378        let (a, b, c) = (0.3, 0.2, 0.1);
379        assert_eq!(
380            round_ties_even_mul_add(a, b, c),
381            round_mul_add(a, b, c, &Mode::NearestTiesEven)
382        );
383        assert_eq!(
384            ciel_mul_add(a, b, c),
385            round_mul_add(a, b, c, &Mode::TowardPosInf)
386        );
387        assert_eq!(
388            floor_mul_add(a, b, c),
389            round_mul_add(a, b, c, &Mode::TowardNegInf)
390        );
391        assert_eq!(
392            trunc_mul_add(a, b, c),
393            round_mul_add(a, b, c, &Mode::TowardZero)
394        );
395
396        let (a, b) = (0.3, 0.2);
397        assert_eq!(
398            round_ties_even_mul_add(a, b, c),
399            round_mul_add(a, b, c, &Mode::NearestTiesEven)
400        );
401        assert_eq!(
402            ciel_mul_add(a, b, c),
403            round_mul_add(a, b, c, &Mode::TowardPosInf)
404        );
405        assert_eq!(
406            floor_mul_add(a, b, c),
407            round_mul_add(a, b, c, &Mode::TowardNegInf)
408        );
409        assert_eq!(
410            trunc_mul_add(a, b, c),
411            round_mul_add(a, b, c, &Mode::TowardZero)
412        );
413    }
414}
415
416/// accrual test
417#[cfg(test)]
418mod test_fn_math {
419    use crate::RoundingMode as Mode;
420
421    use super::*;
422
423    macro_rules! assert_nan {
424        ($a:expr) => {
425            assert!($a.is_nan())
426        };
427    }
428
429    #[test]
430    fn test_sqrt() {
431        let a = 2.0;
432        let e: f64 = 1.4142135623730951;
433        assert_eq!(round_sqrt(a, &Mode::NearestTiesEven), e);
434        assert_eq!(round_sqrt(a, &Mode::TowardPosInf), e);
435        assert_eq!(round_sqrt(a, &Mode::TowardNegInf), e.next_down());
436        assert_eq!(round_sqrt(a, &Mode::TowardZero), e.next_down());
437
438        let a = -2.0;
439        assert_nan!(round_sqrt(a, &Mode::NearestTiesEven));
440        assert_nan!(round_sqrt(a, &Mode::TowardPosInf));
441        assert_nan!(round_sqrt(a, &Mode::TowardNegInf));
442        assert_nan!(round_sqrt(a, &Mode::TowardZero));
443    }
444}
445
446#[cfg(test)]
447mod test_fn_math_mono {
448    use crate::RoundingMode as Mode;
449
450    use super::*;
451
452    #[test]
453    fn test_sqrt() {
454        let a = 2.0;
455        assert_eq!(
456            round_ties_even_sqrt(a),
457            round_sqrt(a, &Mode::NearestTiesEven)
458        );
459        assert_eq!(ciel_sqrt(a), round_sqrt(a, &Mode::TowardPosInf));
460        assert_eq!(floor_sqrt(a), round_sqrt(a, &Mode::TowardNegInf));
461        assert_eq!(trunc_sqrt(a), round_sqrt(a, &Mode::TowardZero));
462    }
463}
464
465#[cfg(test)]
466mod test_trait_arith {
467    use crate::RoundingMode as Mode;
468
469    use super::*;
470
471    #[test]
472    fn test_add() {
473        let (a, b) = (0.1, 0.2);
474        assert_eq!(
475            a.round_add(b, &Mode::NearestTiesEven),
476            round_add(a, b, &Mode::NearestTiesEven)
477        );
478        assert_eq!(
479            a.round_add(b, &Mode::TowardPosInf),
480            round_add(a, b, &Mode::TowardPosInf)
481        );
482        assert_eq!(
483            a.round_add(b, &Mode::TowardNegInf),
484            round_add(a, b, &Mode::TowardNegInf)
485        );
486        assert_eq!(
487            a.round_add(b, &Mode::TowardZero),
488            round_add(a, b, &Mode::TowardZero)
489        );
490
491        let (a, b) = (-0.1, -0.2);
492        assert_eq!(
493            a.round_add(b, &Mode::NearestTiesEven),
494            round_add(a, b, &Mode::NearestTiesEven)
495        );
496        assert_eq!(
497            a.round_add(b, &Mode::TowardPosInf),
498            round_add(a, b, &Mode::TowardPosInf)
499        );
500        assert_eq!(
501            a.round_add(b, &Mode::TowardNegInf),
502            round_add(a, b, &Mode::TowardNegInf)
503        );
504        assert_eq!(
505            a.round_add(b, &Mode::TowardZero),
506            round_add(a, b, &Mode::TowardZero)
507        );
508    }
509
510    #[test]
511    fn test_sub() {
512        let (a, b) = (0.3, 0.01);
513        assert_eq!(
514            a.round_sub(b, &Mode::NearestTiesEven),
515            round_sub(a, b, &Mode::NearestTiesEven)
516        );
517        assert_eq!(
518            a.round_sub(b, &Mode::TowardPosInf),
519            round_sub(a, b, &Mode::TowardPosInf)
520        );
521        assert_eq!(
522            a.round_sub(b, &Mode::TowardNegInf),
523            round_sub(a, b, &Mode::TowardNegInf)
524        );
525        assert_eq!(
526            a.round_sub(b, &Mode::TowardZero),
527            round_sub(a, b, &Mode::TowardZero)
528        );
529
530        let (a, b) = (-0.3, -0.01);
531        assert_eq!(
532            a.round_sub(b, &Mode::NearestTiesEven),
533            round_sub(a, b, &Mode::NearestTiesEven)
534        );
535        assert_eq!(
536            a.round_sub(b, &Mode::TowardPosInf),
537            round_sub(a, b, &Mode::TowardPosInf)
538        );
539        assert_eq!(
540            a.round_sub(b, &Mode::TowardNegInf),
541            round_sub(a, b, &Mode::TowardNegInf)
542        );
543        assert_eq!(
544            a.round_sub(b, &Mode::TowardZero),
545            round_sub(a, b, &Mode::TowardZero)
546        );
547    }
548
549    #[test]
550    fn test_mul() {
551        let (a, b) = (0.3, 0.3);
552        assert_eq!(
553            a.round_mul(b, &Mode::NearestTiesEven),
554            round_mul(a, b, &Mode::NearestTiesEven)
555        );
556        assert_eq!(
557            a.round_mul(b, &Mode::TowardPosInf),
558            round_mul(a, b, &Mode::TowardPosInf)
559        );
560        assert_eq!(
561            a.round_mul(b, &Mode::TowardNegInf),
562            round_mul(a, b, &Mode::TowardNegInf)
563        );
564        assert_eq!(
565            a.round_mul(b, &Mode::TowardZero),
566            round_mul(a, b, &Mode::TowardZero)
567        );
568
569        let (a, b) = (-0.3, 0.3);
570        assert_eq!(
571            a.round_mul(b, &Mode::NearestTiesEven),
572            round_mul(a, b, &Mode::NearestTiesEven)
573        );
574        assert_eq!(
575            a.round_mul(b, &Mode::TowardPosInf),
576            round_mul(a, b, &Mode::TowardPosInf)
577        );
578        assert_eq!(
579            a.round_mul(b, &Mode::TowardNegInf),
580            round_mul(a, b, &Mode::TowardNegInf)
581        );
582        assert_eq!(
583            a.round_mul(b, &Mode::TowardZero),
584            round_mul(a, b, &Mode::TowardZero)
585        );
586    }
587
588    #[test]
589    fn test_div() {
590        let (a, b) = (0.3, 0.2);
591        assert_eq!(
592            a.round_div(b, &Mode::NearestTiesEven),
593            round_div(a, b, &Mode::NearestTiesEven)
594        );
595        assert_eq!(
596            a.round_div(b, &Mode::TowardPosInf),
597            round_div(a, b, &Mode::TowardPosInf)
598        );
599        assert_eq!(
600            a.round_div(b, &Mode::TowardNegInf),
601            round_div(a, b, &Mode::TowardNegInf)
602        );
603        assert_eq!(
604            a.round_div(b, &Mode::TowardZero),
605            round_div(a, b, &Mode::TowardZero)
606        );
607
608        let (a, b) = (-0.3, 0.2);
609        assert_eq!(
610            a.round_div(b, &Mode::NearestTiesEven),
611            round_div(a, b, &Mode::NearestTiesEven)
612        );
613        assert_eq!(
614            a.round_div(b, &Mode::TowardPosInf),
615            round_div(a, b, &Mode::TowardPosInf)
616        );
617        assert_eq!(
618            a.round_div(b, &Mode::TowardNegInf),
619            round_div(a, b, &Mode::TowardNegInf)
620        );
621        assert_eq!(
622            a.round_div(b, &Mode::TowardZero),
623            round_div(a, b, &Mode::TowardZero)
624        );
625    }
626
627    #[test]
628    fn test_mul_add() {
629        let (a, b, c) = (0.3, 0.2, 0.1);
630        assert_eq!(
631            a.round_mul_add(b, c, &Mode::NearestTiesEven),
632            round_mul_add(a, b, c, &Mode::NearestTiesEven)
633        );
634        assert_eq!(
635            a.round_mul_add(b, c, &Mode::TowardPosInf),
636            round_mul_add(a, b, c, &Mode::TowardPosInf)
637        );
638        assert_eq!(
639            a.round_mul_add(b, c, &Mode::TowardNegInf),
640            round_mul_add(a, b, c, &Mode::TowardNegInf)
641        );
642        assert_eq!(
643            a.round_mul_add(b, c, &Mode::TowardZero),
644            round_mul_add(a, b, c, &Mode::TowardZero)
645        );
646
647        let (a, b, c) = (-0.3, 0.2, -0.1);
648        assert_eq!(
649            a.round_mul_add(b, c, &Mode::NearestTiesEven),
650            round_mul_add(a, b, c, &Mode::NearestTiesEven)
651        );
652        assert_eq!(
653            a.round_mul_add(b, c, &Mode::TowardPosInf),
654            round_mul_add(a, b, c, &Mode::TowardPosInf)
655        );
656        assert_eq!(
657            a.round_mul_add(b, c, &Mode::TowardNegInf),
658            round_mul_add(a, b, c, &Mode::TowardNegInf)
659        );
660        assert_eq!(
661            a.round_mul_add(b, c, &Mode::TowardZero),
662            round_mul_add(a, b, c, &Mode::TowardZero)
663        );
664    }
665}
666
667#[cfg(test)]
668mod test_trait_arith_mono {
669    use crate::RoundingMode as Mode;
670
671    use super::*;
672
673    #[test]
674    fn test_add() {
675        let (a, b) = (0.1, 0.2);
676        assert_eq!(
677            a.round_ties_even_add(b),
678            a.round_add(b, &Mode::NearestTiesEven)
679        );
680        assert_eq!(a.ciel_add(b), a.round_add(b, &Mode::TowardPosInf));
681        assert_eq!(a.floor_add(b), a.round_add(b, &Mode::TowardNegInf));
682        assert_eq!(a.trunc_add(b), a.round_add(b, &Mode::TowardZero));
683
684        let (a, b) = (-0.1, -0.2);
685        assert_eq!(
686            a.round_ties_even_add(b),
687            a.round_add(b, &Mode::NearestTiesEven)
688        );
689        assert_eq!(a.ciel_add(b), a.round_add(b, &Mode::TowardPosInf));
690        assert_eq!(a.floor_add(b), a.round_add(b, &Mode::TowardNegInf));
691        assert_eq!(a.trunc_add(b), a.round_add(b, &Mode::TowardZero));
692    }
693
694    #[test]
695    fn test_sub() {
696        let (a, b) = (0.3, 0.01);
697        assert_eq!(
698            a.round_ties_even_sub(b),
699            a.round_sub(b, &Mode::NearestTiesEven)
700        );
701        assert_eq!(a.ciel_sub(b), a.round_sub(b, &Mode::TowardPosInf));
702        assert_eq!(a.floor_sub(b), a.round_sub(b, &Mode::TowardNegInf));
703        assert_eq!(a.trunc_sub(b), a.round_sub(b, &Mode::TowardZero));
704
705        let (a, b) = (-0.3, -0.01);
706        assert_eq!(
707            a.round_ties_even_sub(b),
708            a.round_sub(b, &Mode::NearestTiesEven)
709        );
710        assert_eq!(a.ciel_sub(b), a.round_sub(b, &Mode::TowardPosInf));
711        assert_eq!(a.floor_sub(b), a.round_sub(b, &Mode::TowardNegInf));
712        assert_eq!(a.trunc_sub(b), a.round_sub(b, &Mode::TowardZero));
713    }
714
715    #[test]
716    fn test_mul() {
717        let (a, b) = (0.3, 0.3);
718        assert_eq!(
719            a.round_ties_even_mul(b),
720            a.round_mul(b, &Mode::NearestTiesEven)
721        );
722        assert_eq!(a.ciel_mul(b), a.round_mul(b, &Mode::TowardPosInf));
723        assert_eq!(a.floor_mul(b), a.round_mul(b, &Mode::TowardNegInf));
724        assert_eq!(a.trunc_mul(b), a.round_mul(b, &Mode::TowardZero));
725
726        let (a, b) = (0.3, 0.3);
727        assert_eq!(
728            a.round_ties_even_mul(b),
729            a.round_mul(b, &Mode::NearestTiesEven)
730        );
731        assert_eq!(a.ciel_mul(b), a.round_mul(b, &Mode::TowardPosInf));
732        assert_eq!(a.floor_mul(b), a.round_mul(b, &Mode::TowardNegInf));
733        assert_eq!(a.trunc_mul(b), a.round_mul(b, &Mode::TowardZero));
734    }
735
736    #[test]
737    fn test_div() {
738        let (a, b) = (0.3, 0.2);
739        assert_eq!(
740            a.round_ties_even_div(b),
741            a.round_div(b, &Mode::NearestTiesEven)
742        );
743        assert_eq!(a.ciel_div(b), a.round_div(b, &Mode::TowardPosInf));
744        assert_eq!(a.floor_div(b), a.round_div(b, &Mode::TowardNegInf));
745        assert_eq!(a.trunc_div(b), a.round_div(b, &Mode::TowardZero));
746
747        let (a, b) = (0.3, 0.2);
748        assert_eq!(
749            a.round_ties_even_div(b),
750            a.round_div(b, &Mode::NearestTiesEven)
751        );
752        assert_eq!(a.ciel_div(b), a.round_div(b, &Mode::TowardPosInf));
753        assert_eq!(a.floor_div(b), a.round_div(b, &Mode::TowardNegInf));
754        assert_eq!(a.trunc_div(b), a.round_div(b, &Mode::TowardZero));
755    }
756
757    #[test]
758    fn test_mul_add() {
759        let (a, b, c) = (0.3, 0.2, 0.1);
760        assert_eq!(
761            a.round_ties_even_mul_add(b, c),
762            a.round_mul_add(b, c, &Mode::NearestTiesEven)
763        );
764        assert_eq!(
765            a.ciel_mul_add(b, c),
766            a.round_mul_add(b, c, &Mode::TowardPosInf)
767        );
768        assert_eq!(
769            a.floor_mul_add(b, c),
770            a.round_mul_add(b, c, &Mode::TowardNegInf)
771        );
772        assert_eq!(
773            a.trunc_mul_add(b, c),
774            a.round_mul_add(b, c, &Mode::TowardZero)
775        );
776
777        let (a, b) = (0.3, 0.2);
778        assert_eq!(
779            a.round_ties_even_mul_add(b, c),
780            a.round_mul_add(b, c, &Mode::NearestTiesEven)
781        );
782        assert_eq!(
783            a.ciel_mul_add(b, c),
784            a.round_mul_add(b, c, &Mode::TowardPosInf)
785        );
786        assert_eq!(
787            a.floor_mul_add(b, c),
788            a.round_mul_add(b, c, &Mode::TowardNegInf)
789        );
790        assert_eq!(
791            a.trunc_mul_add(b, c),
792            a.round_mul_add(b, c, &Mode::TowardZero)
793        );
794    }
795}
796
797#[cfg(test)]
798mod test_trait_math {
799    use crate::RoundingMode as Mode;
800
801    use super::*;
802
803    macro_rules! assert_nan {
804        ($a:expr) => {
805            assert!($a.is_nan())
806        };
807    }
808
809    #[test]
810    fn test_sqrt() {
811        let a = 2.0;
812        assert_eq!(
813            a.round_sqrt(&Mode::NearestTiesEven),
814            round_sqrt(a, &Mode::NearestTiesEven)
815        );
816        assert_eq!(
817            a.round_sqrt(&Mode::TowardPosInf),
818            round_sqrt(a, &Mode::TowardPosInf)
819        );
820        assert_eq!(
821            a.round_sqrt(&Mode::TowardNegInf),
822            round_sqrt(a, &Mode::TowardNegInf)
823        );
824        assert_eq!(
825            a.round_sqrt(&Mode::TowardZero),
826            round_sqrt(a, &Mode::TowardZero)
827        );
828
829        let a: f32 = -2.0;
830        assert_nan!(a.round_sqrt(&Mode::NearestTiesEven));
831        assert_nan!(a.round_sqrt(&Mode::TowardPosInf));
832        assert_nan!(a.round_sqrt(&Mode::TowardNegInf));
833        assert_nan!(a.round_sqrt(&Mode::TowardZero));
834    }
835}
836
837#[cfg(test)]
838mod test_trait_math_mono {
839    use crate::RoundingMode as Mode;
840
841    use super::*;
842
843    #[test]
844    fn test_sqrt() {
845        let a = 2.0;
846        assert_eq!(
847            a.round_ties_even_sqrt(),
848            a.round_sqrt(&Mode::NearestTiesEven)
849        );
850        assert_eq!(a.ciel_sqrt(), a.round_sqrt(&Mode::TowardPosInf));
851        assert_eq!(a.floor_sqrt(), a.round_sqrt(&Mode::TowardNegInf));
852        assert_eq!(a.trunc_sqrt(), a.round_sqrt(&Mode::TowardZero));
853    }
854}