glam/f64/
math.rs

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        // Based on https://doc.rust-lang.org/src/std/f64.rs.html#293
95        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::*;