1//! `f32` extension
2
3use crate::float::F32;
4
5/// `f32` extension providing various arithmetic approximations and polyfills
6/// for `std` functionality.
7pub trait F32Ext: Sized {
8 /// Compute absolute value with a constant-time, data-independent
9 /// implementation.
10 fn abs(self) -> f32;
11
12 /// Approximates `acos(x)` in radians in the range `[0, pi]`
13 fn acos(self) -> f32;
14
15 /// Approximates `asin(x)` in radians in the range `[-pi/2, pi/2]`.
16 fn asin(self) -> f32;
17
18 /// Approximates `atan(x)` in radians with a maximum error of `0.002`.
19 fn atan(self) -> f32;
20
21 /// Approximates `atan(x)` normalized to the `[−1,1]` range with a maximum
22 /// error of `0.1620` degrees.
23 fn atan_norm(self) -> f32;
24
25 /// Approximates the four quadrant arctangent `atan2(x)` in radians, with
26 /// a maximum error of `0.002`.
27 fn atan2(self, other: f32) -> f32;
28
29 /// Approximates the four quadrant arctangent.
30 /// Normalized to the `[0,4)` range with a maximum error of `0.1620` degrees.
31 fn atan2_norm(self, other: f32) -> f32;
32
33 /// Approximates floating point ceiling.
34 fn ceil(self) -> f32;
35
36 /// Copies the sign from one number to another and returns it.
37 fn copysign(self, sign: f32) -> f32;
38
39 /// Approximates cosine in radians with a maximum error of `0.002`.
40 fn cos(self) -> f32;
41
42 /// Calculates Euclidean division, the matching method for `rem_euclid`.
43 fn div_euclid(self, other: f32) -> f32;
44
45 /// Approximates `e^x`.
46 fn exp(self) -> f32;
47
48 /// Approximates floating point floor.
49 fn floor(self) -> f32;
50
51 /// Retrieve the fractional part of floating point with sign.
52 fn fract(self) -> f32;
53
54 /// Approximates the length of the hypotenuse of a right-angle triangle given
55 /// legs of length `x` and `y`.
56 fn hypot(self, other: f32) -> f32;
57
58 /// Approximates `1/x` with an average deviation of ~8%.
59 fn inv(self) -> f32;
60
61 /// Approximates inverse square root with an average deviation of ~5%.
62 fn invsqrt(self) -> f32;
63
64 /// Approximates `ln(x)`.
65 fn ln(self) -> f32;
66
67 /// Approximates `log` with an arbitrary base.
68 fn log(self, base: f32) -> f32;
69
70 /// Approximates `log2`.
71 fn log2(self) -> f32;
72
73 /// Approximates `log10`.
74 fn log10(self) -> f32;
75
76 /// Computes `(self * a) + b`.
77 fn mul_add(self, a: f32, b: f32) -> f32;
78
79 /// Approximates `self^n`.
80 fn powf(self, n: f32) -> f32;
81
82 /// Approximates `self^n` where n is an `i32`
83 fn powi(self, n: i32) -> f32;
84
85 /// Returns the reciprocal (inverse) of a number, `1/x`.
86 fn recip(self) -> f32;
87
88 /// Calculates the least nonnegative remainder of `self (mod other)`.
89 fn rem_euclid(self, other: f32) -> f32;
90
91 /// Round the number part of floating point with sign.
92 fn round(self) -> f32;
93
94 /// Returns a number that represents the sign of `self`.
95 fn signum(self) -> f32;
96
97 /// Approximates sine in radians with a maximum error of `0.002`.
98 fn sin(self) -> f32;
99
100 /// Simultaneously computes the sine and cosine of the number, `x`.
101 /// Returns `(sin(x), cos(x))`.
102 fn sin_cos(self) -> (f32, f32);
103
104 /// Approximates square root with an average deviation of ~5%.
105 fn sqrt(self) -> f32;
106
107 /// Approximates `tan(x)` in radians with a maximum error of `0.6`.
108 fn tan(self) -> f32;
109
110 /// Retrieve whole number part of floating point with sign.
111 fn trunc(self) -> f32;
112}
113
114impl F32Ext for f32 {
115 #[inline]
116 fn abs(self) -> f32 {
117 F32(self).abs().0
118 }
119
120 #[inline]
121 fn acos(self) -> f32 {
122 F32(self).acos().0
123 }
124
125 #[inline]
126 fn asin(self) -> f32 {
127 F32(self).asin().0
128 }
129
130 #[inline]
131 fn atan(self) -> f32 {
132 F32(self).atan().0
133 }
134
135 #[inline]
136 fn atan_norm(self) -> f32 {
137 F32(self).atan_norm().0
138 }
139
140 #[inline]
141 fn atan2(self, other: f32) -> f32 {
142 F32(self).atan2(F32(other)).0
143 }
144
145 #[inline]
146 fn atan2_norm(self, other: f32) -> f32 {
147 F32(self).atan2_norm(F32(other)).0
148 }
149
150 #[inline]
151 fn ceil(self) -> f32 {
152 F32(self).ceil().0
153 }
154
155 #[inline]
156 fn copysign(self, sign: f32) -> f32 {
157 F32(self).copysign(F32(sign)).0
158 }
159
160 #[inline]
161 fn cos(self) -> f32 {
162 F32(self).cos().0
163 }
164
165 #[inline]
166 fn div_euclid(self, other: f32) -> f32 {
167 F32(self).div_euclid(F32(other)).0
168 }
169
170 #[inline]
171 fn exp(self) -> f32 {
172 F32(self).exp().0
173 }
174
175 #[inline]
176 fn floor(self) -> f32 {
177 F32(self).floor().0
178 }
179
180 #[inline]
181 fn fract(self) -> f32 {
182 F32(self).fract().0
183 }
184
185 #[inline]
186 fn hypot(self, other: f32) -> f32 {
187 F32(self).hypot(other.into()).0
188 }
189
190 #[inline]
191 fn inv(self) -> f32 {
192 F32(self).inv().0
193 }
194
195 #[inline]
196 fn invsqrt(self) -> f32 {
197 F32(self).invsqrt().0
198 }
199
200 #[inline]
201 fn ln(self) -> f32 {
202 F32(self).ln().0
203 }
204
205 #[inline]
206 fn log(self, base: f32) -> f32 {
207 F32(self).log(F32(base)).0
208 }
209
210 #[inline]
211 fn log2(self) -> f32 {
212 F32(self).log2().0
213 }
214
215 #[inline]
216 fn log10(self) -> f32 {
217 F32(self).log10().0
218 }
219
220 #[inline]
221 fn mul_add(self, a: f32, b: f32) -> f32 {
222 F32(self).mul_add(F32(a), F32(b)).0
223 }
224
225 #[inline]
226 fn powf(self, n: f32) -> f32 {
227 F32(self).powf(F32(n)).0
228 }
229
230 #[inline]
231 fn powi(self, n: i32) -> f32 {
232 F32(self).powi(n).0
233 }
234
235 #[inline]
236 fn recip(self) -> f32 {
237 F32(self).recip().0
238 }
239
240 #[inline]
241 fn rem_euclid(self, other: f32) -> f32 {
242 F32(self).rem_euclid(F32(other)).0
243 }
244
245 #[inline]
246 fn round(self) -> f32 {
247 F32(self).round().0
248 }
249
250 #[inline]
251 fn signum(self) -> f32 {
252 F32(self).signum().0
253 }
254
255 #[inline]
256 fn sin(self) -> f32 {
257 F32(self).sin().0
258 }
259
260 #[inline]
261 fn sin_cos(self) -> (f32, f32) {
262 (F32(self).sin().0, F32(self).cos().0)
263 }
264
265 #[inline]
266 fn sqrt(self) -> f32 {
267 F32(self).sqrt().0
268 }
269
270 #[inline]
271 fn tan(self) -> f32 {
272 F32(self).tan().0
273 }
274
275 #[inline]
276 fn trunc(self) -> f32 {
277 F32(self).trunc().0
278 }
279}
280