1 | //! `f32` extension |
2 | |
3 | use crate::float::F32; |
4 | |
5 | /// `f32` extension providing various arithmetic approximations and polyfills |
6 | /// for `std` functionality. |
7 | pub 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 | |
114 | impl 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 | |