1#[cfg(feature = "libm")]
2mod libm_math {
3 #[inline(always)]
4 pub(crate) fn abs(f: f64) -> f64 {
5 libm::fabs(f)
6 }
7
8 #[inline(always)]
9 pub(crate) fn acos_approx(f: f64) -> f64 {
10 libm::acos(f.clamp(-1.0, 1.0))
11 }
12
13 #[inline(always)]
14 pub(crate) fn asin(f: f64) -> f64 {
15 libm::asin(f)
16 }
17
18 #[inline(always)]
19 pub(crate) fn atan2(f: f64, other: f64) -> f64 {
20 libm::atan2(f, other)
21 }
22
23 #[inline(always)]
24 pub(crate) fn sin(f: f64) -> f64 {
25 libm::sin(f)
26 }
27
28 #[inline(always)]
29 pub(crate) fn sin_cos(f: f64) -> (f64, f64) {
30 libm::sincos(f)
31 }
32
33 #[inline(always)]
34 pub(crate) fn tan(f: f64) -> f64 {
35 libm::tan(f)
36 }
37
38 #[inline(always)]
39 pub(crate) fn sqrt(f: f64) -> f64 {
40 libm::sqrt(f)
41 }
42
43 #[inline(always)]
44 pub(crate) fn copysign(f: f64, sign: f64) -> f64 {
45 libm::copysign(f, sign)
46 }
47
48 #[inline(always)]
49 pub(crate) fn signum(f: f64) -> f64 {
50 if f.is_nan() {
51 f64::NAN
52 } else {
53 copysign(1.0, f)
54 }
55 }
56
57 #[inline(always)]
58 pub(crate) fn round(f: f64) -> f64 {
59 libm::round(f)
60 }
61
62 #[inline(always)]
63 pub(crate) fn trunc(f: f64) -> f64 {
64 libm::trunc(f)
65 }
66
67 #[inline(always)]
68 pub(crate) fn ceil(f: f64) -> f64 {
69 libm::ceil(f)
70 }
71
72 #[inline(always)]
73 pub(crate) fn floor(f: f64) -> f64 {
74 libm::floor(f)
75 }
76
77 #[inline(always)]
78 pub(crate) fn exp(f: f64) -> f64 {
79 libm::exp(f)
80 }
81
82 #[inline(always)]
83 pub(crate) fn powf(f: f64, n: f64) -> f64 {
84 libm::pow(f, n)
85 }
86
87 #[inline(always)]
88 pub(crate) fn mul_add(a: f64, b: f64, c: f64) -> f64 {
89 libm::fma(a, b, c)
90 }
91
92 #[inline]
93 pub fn div_euclid(a: f64, b: f64) -> f64 {
94 let q = libm::trunc(a / b);
96 if a % b < 0.0 {
97 return if b > 0.0 { q - 1.0 } else { q + 1.0 };
98 }
99 q
100 }
101
102 #[inline]
103 pub fn rem_euclid(a: f64, b: f64) -> f64 {
104 let r = a % b;
105 if r < 0.0 {
106 r + abs(b)
107 } else {
108 r
109 }
110 }
111}
112
113#[cfg(not(feature = "libm"))]
114mod std_math {
115 #[inline(always)]
116 pub(crate) fn abs(f: f64) -> f64 {
117 f64::abs(f)
118 }
119
120 #[inline(always)]
121 pub(crate) fn acos_approx(f: f64) -> f64 {
122 f64::acos(f64::clamp(f, -1.0, 1.0))
123 }
124
125 #[inline(always)]
126 pub(crate) fn asin(f: f64) -> f64 {
127 f64::asin(f)
128 }
129
130 #[inline(always)]
131 pub(crate) fn atan2(f: f64, other: f64) -> f64 {
132 f64::atan2(f, other)
133 }
134
135 #[inline(always)]
136 pub(crate) fn sin(f: f64) -> f64 {
137 f64::sin(f)
138 }
139
140 #[inline(always)]
141 pub(crate) fn sin_cos(f: f64) -> (f64, f64) {
142 f64::sin_cos(f)
143 }
144
145 #[inline(always)]
146 pub(crate) fn tan(f: f64) -> f64 {
147 f64::tan(f)
148 }
149
150 #[inline(always)]
151 pub(crate) fn sqrt(f: f64) -> f64 {
152 f64::sqrt(f)
153 }
154
155 #[inline(always)]
156 pub(crate) fn copysign(f: f64, sign: f64) -> f64 {
157 f64::copysign(f, sign)
158 }
159
160 #[inline(always)]
161 pub(crate) fn signum(f: f64) -> f64 {
162 f64::signum(f)
163 }
164
165 #[inline(always)]
166 pub(crate) fn round(f: f64) -> f64 {
167 f64::round(f)
168 }
169
170 #[inline(always)]
171 pub(crate) fn trunc(f: f64) -> f64 {
172 f64::trunc(f)
173 }
174
175 #[inline(always)]
176 pub(crate) fn ceil(f: f64) -> f64 {
177 f64::ceil(f)
178 }
179
180 #[inline(always)]
181 pub(crate) fn floor(f: f64) -> f64 {
182 f64::floor(f)
183 }
184
185 #[inline(always)]
186 pub(crate) fn exp(f: f64) -> f64 {
187 f64::exp(f)
188 }
189
190 #[inline(always)]
191 pub(crate) fn powf(f: f64, n: f64) -> f64 {
192 f64::powf(f, n)
193 }
194
195 #[inline(always)]
196 pub(crate) fn mul_add(a: f64, b: f64, c: f64) -> f64 {
197 f64::mul_add(a, b, c)
198 }
199
200 #[inline]
201 pub fn div_euclid(a: f64, b: f64) -> f64 {
202 f64::div_euclid(a, b)
203 }
204
205 #[inline]
206 pub fn rem_euclid(a: f64, b: f64) -> f64 {
207 f64::rem_euclid(a, b)
208 }
209}
210
211#[cfg(feature = "libm")]
212pub(crate) use libm_math::*;
213
214#[cfg(not(feature = "libm"))]
215pub(crate) use std_math::*;