compiler_builtins/math/libm_math/
fmin_fmax.rs

1/// Return the lesser of two arguments or, if either argument is NaN, the other argument.
2///
3/// This coincides with IEEE 754-2011 `minNum`. The result disregards signed zero (meaning if
4/// the inputs are -0.0 and +0.0, either may be returned).
5#[cfg(f16_enabled)]
6#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
7pub fn fminf16(x: f16, y: f16) -> f16 {
8    super::generic::fmin(x, y)
9}
10
11/// Return the lesser of two arguments or, if either argument is NaN, the other argument.
12///
13/// This coincides with IEEE 754-2011 `minNum`. The result disregards signed zero (meaning if
14/// the inputs are -0.0 and +0.0, either may be returned).
15#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
16pub fn fminf(x: f32, y: f32) -> f32 {
17    super::generic::fmin(x, y)
18}
19
20/// Return the lesser of two arguments or, if either argument is NaN, the other argument.
21///
22/// This coincides with IEEE 754-2011 `minNum`. The result disregards signed zero (meaning if
23/// the inputs are -0.0 and +0.0, either may be returned).
24#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
25pub fn fmin(x: f64, y: f64) -> f64 {
26    super::generic::fmin(x, y)
27}
28
29/// Return the lesser of two arguments or, if either argument is NaN, the other argument.
30///
31/// This coincides with IEEE 754-2011 `minNum`. The result disregards signed zero (meaning if
32/// the inputs are -0.0 and +0.0, either may be returned).
33#[cfg(f128_enabled)]
34#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
35pub fn fminf128(x: f128, y: f128) -> f128 {
36    super::generic::fmin(x, y)
37}
38
39/// Return the greater of two arguments or, if either argument is NaN, the other argument.
40///
41/// This coincides with IEEE 754-2011 `maxNum`. The result disregards signed zero (meaning if
42/// the inputs are -0.0 and +0.0, either may be returned).
43#[cfg(f16_enabled)]
44#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
45pub fn fmaxf16(x: f16, y: f16) -> f16 {
46    super::generic::fmax(x, y)
47}
48
49/// Return the greater of two arguments or, if either argument is NaN, the other argument.
50///
51/// This coincides with IEEE 754-2011 `maxNum`. The result disregards signed zero (meaning if
52/// the inputs are -0.0 and +0.0, either may be returned).
53#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
54pub fn fmaxf(x: f32, y: f32) -> f32 {
55    super::generic::fmax(x, y)
56}
57
58/// Return the greater of two arguments or, if either argument is NaN, the other argument.
59///
60/// This coincides with IEEE 754-2011 `maxNum`. The result disregards signed zero (meaning if
61/// the inputs are -0.0 and +0.0, either may be returned).
62#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
63pub fn fmax(x: f64, y: f64) -> f64 {
64    super::generic::fmax(x, y)
65}
66
67/// Return the greater of two arguments or, if either argument is NaN, the other argument.
68///
69/// This coincides with IEEE 754-2011 `maxNum`. The result disregards signed zero (meaning if
70/// the inputs are -0.0 and +0.0, either may be returned).
71#[cfg(f128_enabled)]
72#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
73pub fn fmaxf128(x: f128, y: f128) -> f128 {
74    super::generic::fmax(x, y)
75}
76
77#[cfg(test)]
78mod tests {
79    use super::*;
80    use crate::support::{Float, Hexf};
81
82    fn fmin_spec_test<F: Float>(f: impl Fn(F, F) -> F) {
83        let cases = [
84            (F::ZERO, F::ZERO, F::ZERO),
85            (F::ONE, F::ONE, F::ONE),
86            (F::ZERO, F::ONE, F::ZERO),
87            (F::ONE, F::ZERO, F::ZERO),
88            (F::ZERO, F::NEG_ONE, F::NEG_ONE),
89            (F::NEG_ONE, F::ZERO, F::NEG_ONE),
90            (F::INFINITY, F::ZERO, F::ZERO),
91            (F::NEG_INFINITY, F::ZERO, F::NEG_INFINITY),
92            (F::NAN, F::ZERO, F::ZERO),
93            (F::ZERO, F::NAN, F::ZERO),
94            (F::NAN, F::NAN, F::NAN),
95        ];
96
97        for (x, y, res) in cases {
98            let val = f(x, y);
99            assert_biteq!(val, res, "fmin({}, {})", Hexf(x), Hexf(y));
100        }
101    }
102
103    #[test]
104    #[cfg(f16_enabled)]
105    fn fmin_spec_tests_f16() {
106        fmin_spec_test::<f16>(fminf16);
107    }
108
109    #[test]
110    fn fmin_spec_tests_f32() {
111        fmin_spec_test::<f32>(fminf);
112    }
113
114    #[test]
115    fn fmin_spec_tests_f64() {
116        fmin_spec_test::<f64>(fmin);
117    }
118
119    #[test]
120    #[cfg(f128_enabled)]
121    fn fmin_spec_tests_f128() {
122        fmin_spec_test::<f128>(fminf128);
123    }
124
125    fn fmax_spec_test<F: Float>(f: impl Fn(F, F) -> F) {
126        let cases = [
127            (F::ZERO, F::ZERO, F::ZERO),
128            (F::ONE, F::ONE, F::ONE),
129            (F::ZERO, F::ONE, F::ONE),
130            (F::ONE, F::ZERO, F::ONE),
131            (F::ZERO, F::NEG_ONE, F::ZERO),
132            (F::NEG_ONE, F::ZERO, F::ZERO),
133            (F::INFINITY, F::ZERO, F::INFINITY),
134            (F::NEG_INFINITY, F::ZERO, F::ZERO),
135            (F::NAN, F::ZERO, F::ZERO),
136            (F::ZERO, F::NAN, F::ZERO),
137            (F::NAN, F::NAN, F::NAN),
138        ];
139
140        for (x, y, res) in cases {
141            let val = f(x, y);
142            assert_biteq!(val, res, "fmax({}, {})", Hexf(x), Hexf(y));
143        }
144    }
145
146    #[test]
147    #[cfg(f16_enabled)]
148    fn fmax_spec_tests_f16() {
149        fmax_spec_test::<f16>(fmaxf16);
150    }
151
152    #[test]
153    fn fmax_spec_tests_f32() {
154        fmax_spec_test::<f32>(fmaxf);
155    }
156
157    #[test]
158    fn fmax_spec_tests_f64() {
159        fmax_spec_test::<f64>(fmax);
160    }
161
162    #[test]
163    #[cfg(f128_enabled)]
164    fn fmax_spec_tests_f128() {
165        fmax_spec_test::<f128>(fmaxf128);
166    }
167}