1 | /* SPDX-License-Identifier: MIT OR Apache-2.0 */ |
2 | //! IEEE 754-2008 `minNum`. This has been superseded by IEEE 754-2019 `minimumNumber`. |
3 | //! |
4 | //! Per the spec, returns the canonicalized result of: |
5 | //! - `x` if `x < y` |
6 | //! - `y` if `y < x` |
7 | //! - The other number if one is NaN |
8 | //! - Otherwise, either `x` or `y`, canonicalized |
9 | //! - -0.0 and +0.0 may be disregarded (unlike newer operations) |
10 | //! |
11 | //! Excluded from our implementation is sNaN handling. |
12 | //! |
13 | //! More on the differences: [link]. |
14 | //! |
15 | //! [link]: https://grouper.ieee.org/groups/msc/ANSI_IEEE-Std-754-2019/background/minNum_maxNum_Removal_Demotion_v3.pdf |
16 | |
17 | use super::super::Float; |
18 | |
19 | pub fn fmin<F: Float>(x: F, y: F) -> F { |
20 | let res: F = if y.is_nan() || x < y { x } else { y }; |
21 | // Canonicalize |
22 | res * F::ONE |
23 | } |
24 | |
25 | #[cfg (test)] |
26 | mod tests { |
27 | use super::*; |
28 | use crate::support::{Hexf, Int}; |
29 | |
30 | fn spec_test<F: Float>() { |
31 | let cases = [ |
32 | (F::ZERO, F::ZERO, F::ZERO), |
33 | (F::ONE, F::ONE, F::ONE), |
34 | (F::ZERO, F::ONE, F::ZERO), |
35 | (F::ONE, F::ZERO, F::ZERO), |
36 | (F::ZERO, F::NEG_ONE, F::NEG_ONE), |
37 | (F::NEG_ONE, F::ZERO, F::NEG_ONE), |
38 | (F::INFINITY, F::ZERO, F::ZERO), |
39 | (F::NEG_INFINITY, F::ZERO, F::NEG_INFINITY), |
40 | (F::NAN, F::ZERO, F::ZERO), |
41 | (F::ZERO, F::NAN, F::ZERO), |
42 | (F::NAN, F::NAN, F::NAN), |
43 | ]; |
44 | |
45 | for (x, y, res) in cases { |
46 | let val = fmin(x, y); |
47 | assert_biteq!(val, res, "fmin({}, {})" , Hexf(x), Hexf(y)); |
48 | } |
49 | } |
50 | |
51 | #[test ] |
52 | #[cfg (f16_enabled)] |
53 | fn spec_tests_f16() { |
54 | spec_test::<f16>(); |
55 | } |
56 | |
57 | #[test ] |
58 | fn spec_tests_f32() { |
59 | spec_test::<f32>(); |
60 | } |
61 | |
62 | #[test ] |
63 | fn spec_tests_f64() { |
64 | spec_test::<f64>(); |
65 | } |
66 | |
67 | #[test ] |
68 | #[cfg (f128_enabled)] |
69 | fn spec_tests_f128() { |
70 | spec_test::<f128>(); |
71 | } |
72 | } |
73 | |