1 | /// Absolute value (magnitude) (f16) |
2 | /// |
3 | /// Calculates the absolute value (magnitude) of the argument `x`, |
4 | /// by direct manipulation of the bit representation of `x`. |
5 | #[cfg (f16_enabled)] |
6 | #[cfg_attr (all(test, assert_no_panic), no_panic::no_panic)] |
7 | pub fn fabsf16(x: f16) -> f16 { |
8 | super::generic::fabs(x) |
9 | } |
10 | |
11 | /// Absolute value (magnitude) (f32) |
12 | /// |
13 | /// Calculates the absolute value (magnitude) of the argument `x`, |
14 | /// by direct manipulation of the bit representation of `x`. |
15 | #[cfg_attr (all(test, assert_no_panic), no_panic::no_panic)] |
16 | pub fn fabsf(x: f32) -> f32 { |
17 | select_implementation! { |
18 | name: fabsf, |
19 | use_arch: all(target_arch = "wasm32" , intrinsics_enabled), |
20 | args: x, |
21 | } |
22 | |
23 | super::generic::fabs(x) |
24 | } |
25 | |
26 | /// Absolute value (magnitude) (f64) |
27 | /// |
28 | /// Calculates the absolute value (magnitude) of the argument `x`, |
29 | /// by direct manipulation of the bit representation of `x`. |
30 | #[cfg_attr (all(test, assert_no_panic), no_panic::no_panic)] |
31 | pub fn fabs(x: f64) -> f64 { |
32 | select_implementation! { |
33 | name: fabs, |
34 | use_arch: all(target_arch = "wasm32" , intrinsics_enabled), |
35 | args: x, |
36 | } |
37 | |
38 | super::generic::fabs(x) |
39 | } |
40 | |
41 | /// Absolute value (magnitude) (f128) |
42 | /// |
43 | /// Calculates the absolute value (magnitude) of the argument `x`, |
44 | /// by direct manipulation of the bit representation of `x`. |
45 | #[cfg (f128_enabled)] |
46 | #[cfg_attr (all(test, assert_no_panic), no_panic::no_panic)] |
47 | pub fn fabsf128(x: f128) -> f128 { |
48 | super::generic::fabs(x) |
49 | } |
50 | |
51 | #[cfg (test)] |
52 | mod tests { |
53 | use super::*; |
54 | use crate::support::Float; |
55 | |
56 | /// Based on https://en.cppreference.com/w/cpp/numeric/math/fabs |
57 | fn spec_test<F: Float>(f: impl Fn(F) -> F) { |
58 | assert_biteq!(f(F::ZERO), F::ZERO); |
59 | assert_biteq!(f(F::NEG_ZERO), F::ZERO); |
60 | assert_biteq!(f(F::INFINITY), F::INFINITY); |
61 | assert_biteq!(f(F::NEG_INFINITY), F::INFINITY); |
62 | assert!(f(F::NAN).is_nan()); |
63 | |
64 | // Not spec rewquired but we expect it |
65 | assert!(f(F::NAN).is_sign_positive()); |
66 | assert!(f(F::from_bits(F::NAN.to_bits() | F::SIGN_MASK)).is_sign_positive()); |
67 | } |
68 | |
69 | #[test ] |
70 | #[cfg (f16_enabled)] |
71 | fn sanity_check_f16() { |
72 | assert_eq!(fabsf16(-1.0f16), 1.0); |
73 | assert_eq!(fabsf16(2.8f16), 2.8); |
74 | } |
75 | |
76 | #[test ] |
77 | #[cfg (f16_enabled)] |
78 | fn spec_tests_f16() { |
79 | spec_test::<f16>(fabsf16); |
80 | } |
81 | |
82 | #[test ] |
83 | fn sanity_check_f32() { |
84 | assert_eq!(fabsf(-1.0f32), 1.0); |
85 | assert_eq!(fabsf(2.8f32), 2.8); |
86 | } |
87 | |
88 | #[test ] |
89 | fn spec_tests_f32() { |
90 | spec_test::<f32>(fabsf); |
91 | } |
92 | |
93 | #[test ] |
94 | fn sanity_check_f64() { |
95 | assert_eq!(fabs(-1.0f64), 1.0); |
96 | assert_eq!(fabs(2.8f64), 2.8); |
97 | } |
98 | |
99 | #[test ] |
100 | fn spec_tests_f64() { |
101 | spec_test::<f64>(fabs); |
102 | } |
103 | |
104 | #[test ] |
105 | #[cfg (f128_enabled)] |
106 | fn sanity_check_f128() { |
107 | assert_eq!(fabsf128(-1.0f128), 1.0); |
108 | assert_eq!(fabsf128(2.8f128), 2.8); |
109 | } |
110 | |
111 | #[test ] |
112 | #[cfg (f128_enabled)] |
113 | fn spec_tests_f128() { |
114 | spec_test::<f128>(fabsf128); |
115 | } |
116 | } |
117 | |