]>
Commit | Line | Data |
---|---|---|
5869c6ff | 1 | //! Constants specific to the `f32` single-precision floating point type. |
c1a9b12d | 2 | //! |
29967ef6 | 3 | //! *[See also the `f32` primitive type](primitive@f32).* |
94b46f34 XL |
4 | //! |
5 | //! Mathematically significant numbers are provided in the `consts` sub-module. | |
74b04a01 | 6 | //! |
5869c6ff XL |
7 | //! For the constants defined directly in this module |
8 | //! (as distinct from those defined in the `consts` sub-module), | |
9 | //! new code should instead use the associated constants | |
10 | //! defined directly on the `f32` type. | |
970d7e83 | 11 | |
85aaf69f | 12 | #![stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 13 | #![allow(missing_docs)] |
970d7e83 | 14 | |
1b1a35ee XL |
15 | #[cfg(test)] |
16 | mod tests; | |
17 | ||
9cc50fc6 | 18 | #[cfg(not(test))] |
532ac7d7 | 19 | use crate::intrinsics; |
9cc50fc6 | 20 | #[cfg(not(test))] |
532ac7d7 | 21 | use crate::sys::cmath; |
1a4d82fc | 22 | |
92a42be0 | 23 | #[stable(feature = "rust1", since = "1.0.0")] |
5869c6ff XL |
24 | #[allow(deprecated, deprecated_in_future)] |
25 | pub use core::f32::{ | |
26 | consts, DIGITS, EPSILON, INFINITY, MANTISSA_DIGITS, MAX, MAX_10_EXP, MAX_EXP, MIN, MIN_10_EXP, | |
27 | MIN_EXP, MIN_POSITIVE, NAN, NEG_INFINITY, RADIX, | |
28 | }; | |
1a4d82fc | 29 | |
c34b1796 | 30 | #[cfg(not(test))] |
94b46f34 | 31 | #[lang = "f32_runtime"] |
c34b1796 | 32 | impl f32 { |
c34b1796 AL |
33 | /// Returns the largest integer less than or equal to a number. |
34 | /// | |
94b46f34 XL |
35 | /// # Examples |
36 | /// | |
c34b1796 | 37 | /// ``` |
532ac7d7 | 38 | /// let f = 3.7_f32; |
c34b1796 | 39 | /// let g = 3.0_f32; |
532ac7d7 | 40 | /// let h = -3.7_f32; |
c34b1796 AL |
41 | /// |
42 | /// assert_eq!(f.floor(), 3.0); | |
43 | /// assert_eq!(g.floor(), 3.0); | |
532ac7d7 | 44 | /// assert_eq!(h.floor(), -4.0); |
c34b1796 | 45 | /// ``` |
60c5eb7d | 46 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
47 | #[stable(feature = "rust1", since = "1.0.0")] |
48 | #[inline] | |
e9174d1e | 49 | pub fn floor(self) -> f32 { |
dfeec247 | 50 | unsafe { intrinsics::floorf32(self) } |
e9174d1e | 51 | } |
970d7e83 | 52 | |
c34b1796 AL |
53 | /// Returns the smallest integer greater than or equal to a number. |
54 | /// | |
94b46f34 XL |
55 | /// # Examples |
56 | /// | |
c34b1796 AL |
57 | /// ``` |
58 | /// let f = 3.01_f32; | |
59 | /// let g = 4.0_f32; | |
60 | /// | |
61 | /// assert_eq!(f.ceil(), 4.0); | |
62 | /// assert_eq!(g.ceil(), 4.0); | |
63 | /// ``` | |
60c5eb7d | 64 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
65 | #[stable(feature = "rust1", since = "1.0.0")] |
66 | #[inline] | |
e9174d1e | 67 | pub fn ceil(self) -> f32 { |
dfeec247 | 68 | unsafe { intrinsics::ceilf32(self) } |
e9174d1e | 69 | } |
970d7e83 | 70 | |
c34b1796 AL |
71 | /// Returns the nearest integer to a number. Round half-way cases away from |
72 | /// `0.0`. | |
73 | /// | |
94b46f34 XL |
74 | /// # Examples |
75 | /// | |
c34b1796 AL |
76 | /// ``` |
77 | /// let f = 3.3_f32; | |
78 | /// let g = -3.3_f32; | |
79 | /// | |
80 | /// assert_eq!(f.round(), 3.0); | |
81 | /// assert_eq!(g.round(), -3.0); | |
82 | /// ``` | |
60c5eb7d | 83 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
84 | #[stable(feature = "rust1", since = "1.0.0")] |
85 | #[inline] | |
e9174d1e SL |
86 | pub fn round(self) -> f32 { |
87 | unsafe { intrinsics::roundf32(self) } | |
88 | } | |
970d7e83 | 89 | |
9346a6ac | 90 | /// Returns the integer part of a number. |
c34b1796 | 91 | /// |
94b46f34 XL |
92 | /// # Examples |
93 | /// | |
c34b1796 | 94 | /// ``` |
532ac7d7 XL |
95 | /// let f = 3.7_f32; |
96 | /// let g = 3.0_f32; | |
97 | /// let h = -3.7_f32; | |
c34b1796 AL |
98 | /// |
99 | /// assert_eq!(f.trunc(), 3.0); | |
532ac7d7 XL |
100 | /// assert_eq!(g.trunc(), 3.0); |
101 | /// assert_eq!(h.trunc(), -3.0); | |
c34b1796 | 102 | /// ``` |
60c5eb7d | 103 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
104 | #[stable(feature = "rust1", since = "1.0.0")] |
105 | #[inline] | |
e9174d1e SL |
106 | pub fn trunc(self) -> f32 { |
107 | unsafe { intrinsics::truncf32(self) } | |
108 | } | |
970d7e83 | 109 | |
c34b1796 AL |
110 | /// Returns the fractional part of a number. |
111 | /// | |
94b46f34 XL |
112 | /// # Examples |
113 | /// | |
c34b1796 | 114 | /// ``` |
dfeec247 XL |
115 | /// let x = 3.6_f32; |
116 | /// let y = -3.6_f32; | |
117 | /// let abs_difference_x = (x.fract() - 0.6).abs(); | |
118 | /// let abs_difference_y = (y.fract() - (-0.6)).abs(); | |
c34b1796 AL |
119 | /// |
120 | /// assert!(abs_difference_x <= f32::EPSILON); | |
121 | /// assert!(abs_difference_y <= f32::EPSILON); | |
122 | /// ``` | |
60c5eb7d | 123 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
124 | #[stable(feature = "rust1", since = "1.0.0")] |
125 | #[inline] | |
60c5eb7d XL |
126 | pub fn fract(self) -> f32 { |
127 | self - self.trunc() | |
128 | } | |
970d7e83 | 129 | |
c34b1796 AL |
130 | /// Computes the absolute value of `self`. Returns `NAN` if the |
131 | /// number is `NAN`. | |
132 | /// | |
94b46f34 XL |
133 | /// # Examples |
134 | /// | |
c34b1796 | 135 | /// ``` |
c34b1796 AL |
136 | /// let x = 3.5_f32; |
137 | /// let y = -3.5_f32; | |
138 | /// | |
139 | /// let abs_difference_x = (x.abs() - x).abs(); | |
140 | /// let abs_difference_y = (y.abs() - (-y)).abs(); | |
141 | /// | |
142 | /// assert!(abs_difference_x <= f32::EPSILON); | |
143 | /// assert!(abs_difference_y <= f32::EPSILON); | |
144 | /// | |
145 | /// assert!(f32::NAN.abs().is_nan()); | |
146 | /// ``` | |
60c5eb7d | 147 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
148 | #[stable(feature = "rust1", since = "1.0.0")] |
149 | #[inline] | |
83c7162d XL |
150 | pub fn abs(self) -> f32 { |
151 | unsafe { intrinsics::fabsf32(self) } | |
152 | } | |
970d7e83 | 153 | |
c34b1796 AL |
154 | /// Returns a number that represents the sign of `self`. |
155 | /// | |
156 | /// - `1.0` if the number is positive, `+0.0` or `INFINITY` | |
157 | /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` | |
158 | /// - `NAN` if the number is `NAN` | |
159 | /// | |
94b46f34 XL |
160 | /// # Examples |
161 | /// | |
c34b1796 | 162 | /// ``` |
c34b1796 AL |
163 | /// let f = 3.5_f32; |
164 | /// | |
165 | /// assert_eq!(f.signum(), 1.0); | |
166 | /// assert_eq!(f32::NEG_INFINITY.signum(), -1.0); | |
167 | /// | |
168 | /// assert!(f32::NAN.signum().is_nan()); | |
169 | /// ``` | |
60c5eb7d | 170 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
171 | #[stable(feature = "rust1", since = "1.0.0")] |
172 | #[inline] | |
83c7162d | 173 | pub fn signum(self) -> f32 { |
f9f354fc | 174 | if self.is_nan() { Self::NAN } else { 1.0_f32.copysign(self) } |
83c7162d | 175 | } |
970d7e83 | 176 | |
0bf4aa26 | 177 | /// Returns a number composed of the magnitude of `self` and the sign of |
532ac7d7 | 178 | /// `sign`. |
0bf4aa26 | 179 | /// |
532ac7d7 | 180 | /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise |
0bf4aa26 | 181 | /// equal to `-self`. If `self` is a `NAN`, then a `NAN` with the sign of |
532ac7d7 | 182 | /// `sign` is returned. |
0bf4aa26 XL |
183 | /// |
184 | /// # Examples | |
185 | /// | |
186 | /// ``` | |
0bf4aa26 XL |
187 | /// let f = 3.5_f32; |
188 | /// | |
189 | /// assert_eq!(f.copysign(0.42), 3.5_f32); | |
190 | /// assert_eq!(f.copysign(-0.42), -3.5_f32); | |
191 | /// assert_eq!((-f).copysign(0.42), 3.5_f32); | |
192 | /// assert_eq!((-f).copysign(-0.42), -3.5_f32); | |
193 | /// | |
194 | /// assert!(f32::NAN.copysign(1.0).is_nan()); | |
195 | /// ``` | |
60c5eb7d | 196 | #[must_use = "method returns a new number and does not mutate the original value"] |
0bf4aa26 | 197 | #[inline] |
532ac7d7 XL |
198 | #[stable(feature = "copysign", since = "1.35.0")] |
199 | pub fn copysign(self, sign: f32) -> f32 { | |
200 | unsafe { intrinsics::copysignf32(self, sign) } | |
0bf4aa26 XL |
201 | } |
202 | ||
c34b1796 | 203 | /// Fused multiply-add. Computes `(self * a) + b` with only one rounding |
94b46f34 XL |
204 | /// error, yielding a more accurate result than an unfused multiply-add. |
205 | /// | |
fc512014 XL |
206 | /// Using `mul_add` *may* be more performant than an unfused multiply-add if |
207 | /// the target architecture has a dedicated `fma` CPU instruction. However, | |
208 | /// this is not always true, and will be heavily dependant on designing | |
209 | /// algorithms with specific target hardware in mind. | |
94b46f34 XL |
210 | /// |
211 | /// # Examples | |
c34b1796 AL |
212 | /// |
213 | /// ``` | |
c34b1796 AL |
214 | /// let m = 10.0_f32; |
215 | /// let x = 4.0_f32; | |
216 | /// let b = 60.0_f32; | |
217 | /// | |
218 | /// // 100.0 | |
e1599b0c | 219 | /// let abs_difference = (m.mul_add(x, b) - ((m * x) + b)).abs(); |
c34b1796 AL |
220 | /// |
221 | /// assert!(abs_difference <= f32::EPSILON); | |
222 | /// ``` | |
60c5eb7d | 223 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
224 | #[stable(feature = "rust1", since = "1.0.0")] |
225 | #[inline] | |
e9174d1e SL |
226 | pub fn mul_add(self, a: f32, b: f32) -> f32 { |
227 | unsafe { intrinsics::fmaf32(self, a, b) } | |
228 | } | |
c34b1796 | 229 | |
0731742a | 230 | /// Calculates Euclidean division, the matching method for `rem_euclid`. |
83c7162d XL |
231 | /// |
232 | /// This computes the integer `n` such that | |
0731742a | 233 | /// `self = n * rhs + self.rem_euclid(rhs)`. |
83c7162d XL |
234 | /// In other words, the result is `self / rhs` rounded to the integer `n` |
235 | /// such that `self >= n * rhs`. | |
c34b1796 | 236 | /// |
94b46f34 XL |
237 | /// # Examples |
238 | /// | |
c34b1796 | 239 | /// ``` |
83c7162d XL |
240 | /// let a: f32 = 7.0; |
241 | /// let b = 4.0; | |
0731742a XL |
242 | /// assert_eq!(a.div_euclid(b), 1.0); // 7.0 > 4.0 * 1.0 |
243 | /// assert_eq!((-a).div_euclid(b), -2.0); // -7.0 >= 4.0 * -2.0 | |
244 | /// assert_eq!(a.div_euclid(-b), -1.0); // 7.0 >= -4.0 * -1.0 | |
245 | /// assert_eq!((-a).div_euclid(-b), 2.0); // -7.0 >= -4.0 * 2.0 | |
83c7162d | 246 | /// ``` |
60c5eb7d | 247 | #[must_use = "method returns a new number and does not mutate the original value"] |
83c7162d | 248 | #[inline] |
416331ca | 249 | #[stable(feature = "euclidean_division", since = "1.38.0")] |
0731742a | 250 | pub fn div_euclid(self, rhs: f32) -> f32 { |
83c7162d XL |
251 | let q = (self / rhs).trunc(); |
252 | if self % rhs < 0.0 { | |
60c5eb7d | 253 | return if rhs > 0.0 { q - 1.0 } else { q + 1.0 }; |
83c7162d XL |
254 | } |
255 | q | |
256 | } | |
257 | ||
0731742a | 258 | /// Calculates the least nonnegative remainder of `self (mod rhs)`. |
c34b1796 | 259 | /// |
8faf50e0 XL |
260 | /// In particular, the return value `r` satisfies `0.0 <= r < rhs.abs()` in |
261 | /// most cases. However, due to a floating point round-off error it can | |
262 | /// result in `r == rhs.abs()`, violating the mathematical definition, if | |
263 | /// `self` is much smaller than `rhs.abs()` in magnitude and `self < 0.0`. | |
264 | /// This result is not an element of the function's codomain, but it is the | |
265 | /// closest floating point number in the real numbers and thus fulfills the | |
0731742a | 266 | /// property `self == self.div_euclid(rhs) * rhs + self.rem_euclid(rhs)` |
8faf50e0 | 267 | /// approximatively. |
c34b1796 | 268 | /// |
94b46f34 XL |
269 | /// # Examples |
270 | /// | |
c34b1796 | 271 | /// ``` |
83c7162d XL |
272 | /// let a: f32 = 7.0; |
273 | /// let b = 4.0; | |
0731742a XL |
274 | /// assert_eq!(a.rem_euclid(b), 3.0); |
275 | /// assert_eq!((-a).rem_euclid(b), 1.0); | |
276 | /// assert_eq!(a.rem_euclid(-b), 3.0); | |
277 | /// assert_eq!((-a).rem_euclid(-b), 1.0); | |
8faf50e0 | 278 | /// // limitation due to round-off error |
ba9703b0 | 279 | /// assert!((-f32::EPSILON).rem_euclid(3.0) != 0.0); |
83c7162d | 280 | /// ``` |
60c5eb7d | 281 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 | 282 | #[inline] |
416331ca | 283 | #[stable(feature = "euclidean_division", since = "1.38.0")] |
0731742a | 284 | pub fn rem_euclid(self, rhs: f32) -> f32 { |
83c7162d | 285 | let r = self % rhs; |
60c5eb7d | 286 | if r < 0.0 { r + rhs.abs() } else { r } |
83c7162d XL |
287 | } |
288 | ||
9346a6ac | 289 | /// Raises a number to an integer power. |
c34b1796 AL |
290 | /// |
291 | /// Using this function is generally faster than using `powf` | |
292 | /// | |
94b46f34 XL |
293 | /// # Examples |
294 | /// | |
c34b1796 | 295 | /// ``` |
c34b1796 | 296 | /// let x = 2.0_f32; |
e1599b0c | 297 | /// let abs_difference = (x.powi(2) - (x * x)).abs(); |
c34b1796 AL |
298 | /// |
299 | /// assert!(abs_difference <= f32::EPSILON); | |
300 | /// ``` | |
60c5eb7d | 301 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
302 | #[stable(feature = "rust1", since = "1.0.0")] |
303 | #[inline] | |
83c7162d XL |
304 | pub fn powi(self, n: i32) -> f32 { |
305 | unsafe { intrinsics::powif32(self, n) } | |
306 | } | |
c34b1796 | 307 | |
9346a6ac | 308 | /// Raises a number to a floating point power. |
c34b1796 | 309 | /// |
94b46f34 XL |
310 | /// # Examples |
311 | /// | |
c34b1796 | 312 | /// ``` |
c34b1796 | 313 | /// let x = 2.0_f32; |
e1599b0c | 314 | /// let abs_difference = (x.powf(2.0) - (x * x)).abs(); |
c34b1796 AL |
315 | /// |
316 | /// assert!(abs_difference <= f32::EPSILON); | |
317 | /// ``` | |
60c5eb7d | 318 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
319 | #[stable(feature = "rust1", since = "1.0.0")] |
320 | #[inline] | |
e9174d1e | 321 | pub fn powf(self, n: f32) -> f32 { |
dfeec247 | 322 | unsafe { intrinsics::powf32(self, n) } |
e9174d1e | 323 | } |
c34b1796 | 324 | |
dfeec247 | 325 | /// Returns the square root of a number. |
c34b1796 AL |
326 | /// |
327 | /// Returns NaN if `self` is a negative number. | |
328 | /// | |
94b46f34 XL |
329 | /// # Examples |
330 | /// | |
c34b1796 | 331 | /// ``` |
c34b1796 AL |
332 | /// let positive = 4.0_f32; |
333 | /// let negative = -4.0_f32; | |
334 | /// | |
335 | /// let abs_difference = (positive.sqrt() - 2.0).abs(); | |
336 | /// | |
337 | /// assert!(abs_difference <= f32::EPSILON); | |
338 | /// assert!(negative.sqrt().is_nan()); | |
339 | /// ``` | |
60c5eb7d | 340 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
341 | #[stable(feature = "rust1", since = "1.0.0")] |
342 | #[inline] | |
e9174d1e | 343 | pub fn sqrt(self) -> f32 { |
dfeec247 | 344 | unsafe { intrinsics::sqrtf32(self) } |
e9174d1e | 345 | } |
c34b1796 | 346 | |
c34b1796 AL |
347 | /// Returns `e^(self)`, (the exponential function). |
348 | /// | |
94b46f34 XL |
349 | /// # Examples |
350 | /// | |
c34b1796 | 351 | /// ``` |
c34b1796 AL |
352 | /// let one = 1.0f32; |
353 | /// // e^1 | |
354 | /// let e = one.exp(); | |
355 | /// | |
356 | /// // ln(e) - 1 == 0 | |
357 | /// let abs_difference = (e.ln() - 1.0).abs(); | |
358 | /// | |
359 | /// assert!(abs_difference <= f32::EPSILON); | |
360 | /// ``` | |
60c5eb7d | 361 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
362 | #[stable(feature = "rust1", since = "1.0.0")] |
363 | #[inline] | |
e9174d1e | 364 | pub fn exp(self) -> f32 { |
dfeec247 | 365 | unsafe { intrinsics::expf32(self) } |
e9174d1e | 366 | } |
c34b1796 AL |
367 | |
368 | /// Returns `2^(self)`. | |
369 | /// | |
94b46f34 XL |
370 | /// # Examples |
371 | /// | |
c34b1796 | 372 | /// ``` |
c34b1796 AL |
373 | /// let f = 2.0f32; |
374 | /// | |
375 | /// // 2^2 - 4 == 0 | |
376 | /// let abs_difference = (f.exp2() - 4.0).abs(); | |
377 | /// | |
378 | /// assert!(abs_difference <= f32::EPSILON); | |
379 | /// ``` | |
60c5eb7d | 380 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
381 | #[stable(feature = "rust1", since = "1.0.0")] |
382 | #[inline] | |
e9174d1e SL |
383 | pub fn exp2(self) -> f32 { |
384 | unsafe { intrinsics::exp2f32(self) } | |
385 | } | |
c34b1796 AL |
386 | |
387 | /// Returns the natural logarithm of the number. | |
388 | /// | |
94b46f34 XL |
389 | /// # Examples |
390 | /// | |
c34b1796 | 391 | /// ``` |
c34b1796 AL |
392 | /// let one = 1.0f32; |
393 | /// // e^1 | |
394 | /// let e = one.exp(); | |
395 | /// | |
396 | /// // ln(e) - 1 == 0 | |
397 | /// let abs_difference = (e.ln() - 1.0).abs(); | |
398 | /// | |
399 | /// assert!(abs_difference <= f32::EPSILON); | |
400 | /// ``` | |
60c5eb7d | 401 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
402 | #[stable(feature = "rust1", since = "1.0.0")] |
403 | #[inline] | |
e9174d1e | 404 | pub fn ln(self) -> f32 { |
dfeec247 | 405 | unsafe { intrinsics::logf32(self) } |
e9174d1e | 406 | } |
c34b1796 AL |
407 | |
408 | /// Returns the logarithm of the number with respect to an arbitrary base. | |
409 | /// | |
2c00a5a8 XL |
410 | /// The result may not be correctly rounded owing to implementation details; |
411 | /// `self.log2()` can produce more accurate results for base 2, and | |
412 | /// `self.log10()` can produce more accurate results for base 10. | |
413 | /// | |
94b46f34 XL |
414 | /// # Examples |
415 | /// | |
c34b1796 | 416 | /// ``` |
2c00a5a8 | 417 | /// let five = 5.0f32; |
c34b1796 | 418 | /// |
2c00a5a8 XL |
419 | /// // log5(5) - 1 == 0 |
420 | /// let abs_difference = (five.log(5.0) - 1.0).abs(); | |
c34b1796 | 421 | /// |
2c00a5a8 | 422 | /// assert!(abs_difference <= f32::EPSILON); |
c34b1796 | 423 | /// ``` |
60c5eb7d | 424 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
425 | #[stable(feature = "rust1", since = "1.0.0")] |
426 | #[inline] | |
60c5eb7d XL |
427 | pub fn log(self, base: f32) -> f32 { |
428 | self.ln() / base.ln() | |
429 | } | |
c34b1796 AL |
430 | |
431 | /// Returns the base 2 logarithm of the number. | |
432 | /// | |
94b46f34 XL |
433 | /// # Examples |
434 | /// | |
c34b1796 | 435 | /// ``` |
c34b1796 AL |
436 | /// let two = 2.0f32; |
437 | /// | |
438 | /// // log2(2) - 1 == 0 | |
439 | /// let abs_difference = (two.log2() - 1.0).abs(); | |
440 | /// | |
441 | /// assert!(abs_difference <= f32::EPSILON); | |
442 | /// ``` | |
60c5eb7d | 443 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
444 | #[stable(feature = "rust1", since = "1.0.0")] |
445 | #[inline] | |
e9174d1e | 446 | pub fn log2(self) -> f32 { |
a7813a04 | 447 | #[cfg(target_os = "android")] |
532ac7d7 | 448 | return crate::sys::android::log2f32(self); |
a7813a04 XL |
449 | #[cfg(not(target_os = "android"))] |
450 | return unsafe { intrinsics::log2f32(self) }; | |
e9174d1e | 451 | } |
c34b1796 AL |
452 | |
453 | /// Returns the base 10 logarithm of the number. | |
454 | /// | |
94b46f34 XL |
455 | /// # Examples |
456 | /// | |
c34b1796 | 457 | /// ``` |
c34b1796 AL |
458 | /// let ten = 10.0f32; |
459 | /// | |
460 | /// // log10(10) - 1 == 0 | |
461 | /// let abs_difference = (ten.log10() - 1.0).abs(); | |
462 | /// | |
463 | /// assert!(abs_difference <= f32::EPSILON); | |
464 | /// ``` | |
60c5eb7d | 465 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
466 | #[stable(feature = "rust1", since = "1.0.0")] |
467 | #[inline] | |
e9174d1e | 468 | pub fn log10(self) -> f32 { |
dfeec247 | 469 | unsafe { intrinsics::log10f32(self) } |
e9174d1e | 470 | } |
c34b1796 | 471 | |
c34b1796 AL |
472 | /// The positive difference of two numbers. |
473 | /// | |
474 | /// * If `self <= other`: `0:0` | |
475 | /// * Else: `self - other` | |
476 | /// | |
94b46f34 XL |
477 | /// # Examples |
478 | /// | |
c34b1796 | 479 | /// ``` |
c34b1796 AL |
480 | /// let x = 3.0f32; |
481 | /// let y = -3.0f32; | |
482 | /// | |
483 | /// let abs_difference_x = (x.abs_sub(1.0) - 2.0).abs(); | |
484 | /// let abs_difference_y = (y.abs_sub(1.0) - 0.0).abs(); | |
485 | /// | |
486 | /// assert!(abs_difference_x <= f32::EPSILON); | |
487 | /// assert!(abs_difference_y <= f32::EPSILON); | |
488 | /// ``` | |
60c5eb7d | 489 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
490 | #[stable(feature = "rust1", since = "1.0.0")] |
491 | #[inline] | |
60c5eb7d XL |
492 | #[rustc_deprecated( |
493 | since = "1.10.0", | |
494 | reason = "you probably meant `(self - other).abs()`: \ | |
495 | this operation is `(self - other).max(0.0)` \ | |
496 | except that `abs_sub` also propagates NaNs (also \ | |
497 | known as `fdimf` in C). If you truly need the positive \ | |
498 | difference, consider using that expression or the C function \ | |
499 | `fdimf`, depending on how you wish to handle NaN (please consider \ | |
500 | filing an issue describing your use-case too)." | |
501 | )] | |
c34b1796 AL |
502 | pub fn abs_sub(self, other: f32) -> f32 { |
503 | unsafe { cmath::fdimf(self, other) } | |
504 | } | |
505 | ||
6a06907d | 506 | /// Returns the cube root of a number. |
c34b1796 | 507 | /// |
94b46f34 XL |
508 | /// # Examples |
509 | /// | |
c34b1796 | 510 | /// ``` |
c34b1796 AL |
511 | /// let x = 8.0f32; |
512 | /// | |
513 | /// // x^(1/3) - 2 == 0 | |
514 | /// let abs_difference = (x.cbrt() - 2.0).abs(); | |
515 | /// | |
516 | /// assert!(abs_difference <= f32::EPSILON); | |
517 | /// ``` | |
60c5eb7d | 518 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
519 | #[stable(feature = "rust1", since = "1.0.0")] |
520 | #[inline] | |
521 | pub fn cbrt(self) -> f32 { | |
522 | unsafe { cmath::cbrtf(self) } | |
523 | } | |
524 | ||
9346a6ac | 525 | /// Calculates the length of the hypotenuse of a right-angle triangle given |
c34b1796 AL |
526 | /// legs of length `x` and `y`. |
527 | /// | |
94b46f34 XL |
528 | /// # Examples |
529 | /// | |
c34b1796 | 530 | /// ``` |
c34b1796 AL |
531 | /// let x = 2.0f32; |
532 | /// let y = 3.0f32; | |
533 | /// | |
534 | /// // sqrt(x^2 + y^2) | |
535 | /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs(); | |
536 | /// | |
537 | /// assert!(abs_difference <= f32::EPSILON); | |
538 | /// ``` | |
60c5eb7d | 539 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
540 | #[stable(feature = "rust1", since = "1.0.0")] |
541 | #[inline] | |
542 | pub fn hypot(self, other: f32) -> f32 { | |
543 | unsafe { cmath::hypotf(self, other) } | |
544 | } | |
545 | ||
546 | /// Computes the sine of a number (in radians). | |
547 | /// | |
94b46f34 XL |
548 | /// # Examples |
549 | /// | |
c34b1796 | 550 | /// ``` |
ba9703b0 | 551 | /// let x = std::f32::consts::FRAC_PI_2; |
c34b1796 AL |
552 | /// |
553 | /// let abs_difference = (x.sin() - 1.0).abs(); | |
554 | /// | |
555 | /// assert!(abs_difference <= f32::EPSILON); | |
556 | /// ``` | |
60c5eb7d | 557 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
558 | #[stable(feature = "rust1", since = "1.0.0")] |
559 | #[inline] | |
560 | pub fn sin(self) -> f32 { | |
dfeec247 | 561 | unsafe { intrinsics::sinf32(self) } |
c34b1796 AL |
562 | } |
563 | ||
564 | /// Computes the cosine of a number (in radians). | |
565 | /// | |
94b46f34 XL |
566 | /// # Examples |
567 | /// | |
c34b1796 | 568 | /// ``` |
ba9703b0 | 569 | /// let x = 2.0 * std::f32::consts::PI; |
c34b1796 AL |
570 | /// |
571 | /// let abs_difference = (x.cos() - 1.0).abs(); | |
572 | /// | |
573 | /// assert!(abs_difference <= f32::EPSILON); | |
574 | /// ``` | |
60c5eb7d | 575 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
576 | #[stable(feature = "rust1", since = "1.0.0")] |
577 | #[inline] | |
578 | pub fn cos(self) -> f32 { | |
dfeec247 | 579 | unsafe { intrinsics::cosf32(self) } |
c34b1796 AL |
580 | } |
581 | ||
582 | /// Computes the tangent of a number (in radians). | |
583 | /// | |
94b46f34 XL |
584 | /// # Examples |
585 | /// | |
c34b1796 | 586 | /// ``` |
ba9703b0 | 587 | /// let x = std::f32::consts::FRAC_PI_4; |
c34b1796 AL |
588 | /// let abs_difference = (x.tan() - 1.0).abs(); |
589 | /// | |
3157f602 | 590 | /// assert!(abs_difference <= f32::EPSILON); |
c34b1796 | 591 | /// ``` |
60c5eb7d | 592 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
593 | #[stable(feature = "rust1", since = "1.0.0")] |
594 | #[inline] | |
595 | pub fn tan(self) -> f32 { | |
596 | unsafe { cmath::tanf(self) } | |
597 | } | |
598 | ||
599 | /// Computes the arcsine of a number. Return value is in radians in | |
600 | /// the range [-pi/2, pi/2] or NaN if the number is outside the range | |
601 | /// [-1, 1]. | |
602 | /// | |
94b46f34 XL |
603 | /// # Examples |
604 | /// | |
c34b1796 | 605 | /// ``` |
ba9703b0 | 606 | /// let f = std::f32::consts::FRAC_PI_2; |
c34b1796 AL |
607 | /// |
608 | /// // asin(sin(pi/2)) | |
ba9703b0 | 609 | /// let abs_difference = (f.sin().asin() - std::f32::consts::FRAC_PI_2).abs(); |
c34b1796 AL |
610 | /// |
611 | /// assert!(abs_difference <= f32::EPSILON); | |
612 | /// ``` | |
60c5eb7d | 613 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
614 | #[stable(feature = "rust1", since = "1.0.0")] |
615 | #[inline] | |
616 | pub fn asin(self) -> f32 { | |
617 | unsafe { cmath::asinf(self) } | |
618 | } | |
619 | ||
620 | /// Computes the arccosine of a number. Return value is in radians in | |
621 | /// the range [0, pi] or NaN if the number is outside the range | |
622 | /// [-1, 1]. | |
623 | /// | |
94b46f34 XL |
624 | /// # Examples |
625 | /// | |
c34b1796 | 626 | /// ``` |
ba9703b0 | 627 | /// let f = std::f32::consts::FRAC_PI_4; |
c34b1796 AL |
628 | /// |
629 | /// // acos(cos(pi/4)) | |
ba9703b0 | 630 | /// let abs_difference = (f.cos().acos() - std::f32::consts::FRAC_PI_4).abs(); |
c34b1796 AL |
631 | /// |
632 | /// assert!(abs_difference <= f32::EPSILON); | |
633 | /// ``` | |
60c5eb7d | 634 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
635 | #[stable(feature = "rust1", since = "1.0.0")] |
636 | #[inline] | |
637 | pub fn acos(self) -> f32 { | |
638 | unsafe { cmath::acosf(self) } | |
639 | } | |
640 | ||
641 | /// Computes the arctangent of a number. Return value is in radians in the | |
642 | /// range [-pi/2, pi/2]; | |
643 | /// | |
94b46f34 XL |
644 | /// # Examples |
645 | /// | |
c34b1796 | 646 | /// ``` |
c34b1796 AL |
647 | /// let f = 1.0f32; |
648 | /// | |
649 | /// // atan(tan(1)) | |
3157f602 | 650 | /// let abs_difference = (f.tan().atan() - 1.0).abs(); |
c34b1796 AL |
651 | /// |
652 | /// assert!(abs_difference <= f32::EPSILON); | |
653 | /// ``` | |
60c5eb7d | 654 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
655 | #[stable(feature = "rust1", since = "1.0.0")] |
656 | #[inline] | |
657 | pub fn atan(self) -> f32 { | |
658 | unsafe { cmath::atanf(self) } | |
659 | } | |
660 | ||
0531ce1d | 661 | /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`) in radians. |
c34b1796 AL |
662 | /// |
663 | /// * `x = 0`, `y = 0`: `0` | |
664 | /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]` | |
665 | /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]` | |
666 | /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)` | |
667 | /// | |
94b46f34 XL |
668 | /// # Examples |
669 | /// | |
c34b1796 | 670 | /// ``` |
0531ce1d XL |
671 | /// // Positive angles measured counter-clockwise |
672 | /// // from positive x axis | |
673 | /// // -pi/4 radians (45 deg clockwise) | |
c34b1796 AL |
674 | /// let x1 = 3.0f32; |
675 | /// let y1 = -3.0f32; | |
676 | /// | |
0531ce1d | 677 | /// // 3pi/4 radians (135 deg counter-clockwise) |
c34b1796 AL |
678 | /// let x2 = -3.0f32; |
679 | /// let y2 = 3.0f32; | |
680 | /// | |
ba9703b0 XL |
681 | /// let abs_difference_1 = (y1.atan2(x1) - (-std::f32::consts::FRAC_PI_4)).abs(); |
682 | /// let abs_difference_2 = (y2.atan2(x2) - (3.0 * std::f32::consts::FRAC_PI_4)).abs(); | |
c34b1796 AL |
683 | /// |
684 | /// assert!(abs_difference_1 <= f32::EPSILON); | |
685 | /// assert!(abs_difference_2 <= f32::EPSILON); | |
686 | /// ``` | |
60c5eb7d | 687 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
688 | #[stable(feature = "rust1", since = "1.0.0")] |
689 | #[inline] | |
690 | pub fn atan2(self, other: f32) -> f32 { | |
691 | unsafe { cmath::atan2f(self, other) } | |
692 | } | |
693 | ||
694 | /// Simultaneously computes the sine and cosine of the number, `x`. Returns | |
695 | /// `(sin(x), cos(x))`. | |
696 | /// | |
94b46f34 XL |
697 | /// # Examples |
698 | /// | |
c34b1796 | 699 | /// ``` |
ba9703b0 | 700 | /// let x = std::f32::consts::FRAC_PI_4; |
c34b1796 AL |
701 | /// let f = x.sin_cos(); |
702 | /// | |
703 | /// let abs_difference_0 = (f.0 - x.sin()).abs(); | |
704 | /// let abs_difference_1 = (f.1 - x.cos()).abs(); | |
705 | /// | |
706 | /// assert!(abs_difference_0 <= f32::EPSILON); | |
a7813a04 | 707 | /// assert!(abs_difference_1 <= f32::EPSILON); |
c34b1796 AL |
708 | /// ``` |
709 | #[stable(feature = "rust1", since = "1.0.0")] | |
710 | #[inline] | |
711 | pub fn sin_cos(self) -> (f32, f32) { | |
712 | (self.sin(), self.cos()) | |
713 | } | |
714 | ||
715 | /// Returns `e^(self) - 1` in a way that is accurate even if the | |
716 | /// number is close to zero. | |
717 | /// | |
94b46f34 XL |
718 | /// # Examples |
719 | /// | |
c34b1796 | 720 | /// ``` |
29967ef6 | 721 | /// let x = 1e-8_f32; |
c34b1796 | 722 | /// |
29967ef6 XL |
723 | /// // for very small x, e^x is approximately 1 + x + x^2 / 2 |
724 | /// let approx = x + x * x / 2.0; | |
725 | /// let abs_difference = (x.exp_m1() - approx).abs(); | |
c34b1796 | 726 | /// |
29967ef6 | 727 | /// assert!(abs_difference < 1e-10); |
c34b1796 | 728 | /// ``` |
60c5eb7d | 729 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
730 | #[stable(feature = "rust1", since = "1.0.0")] |
731 | #[inline] | |
732 | pub fn exp_m1(self) -> f32 { | |
733 | unsafe { cmath::expm1f(self) } | |
734 | } | |
735 | ||
736 | /// Returns `ln(1+n)` (natural logarithm) more accurately than if | |
737 | /// the operations were performed separately. | |
738 | /// | |
94b46f34 XL |
739 | /// # Examples |
740 | /// | |
c34b1796 | 741 | /// ``` |
29967ef6 | 742 | /// let x = 1e-8_f32; |
c34b1796 | 743 | /// |
29967ef6 XL |
744 | /// // for very small x, ln(1 + x) is approximately x - x^2 / 2 |
745 | /// let approx = x - x * x / 2.0; | |
746 | /// let abs_difference = (x.ln_1p() - approx).abs(); | |
c34b1796 | 747 | /// |
29967ef6 | 748 | /// assert!(abs_difference < 1e-10); |
c34b1796 | 749 | /// ``` |
60c5eb7d | 750 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
751 | #[stable(feature = "rust1", since = "1.0.0")] |
752 | #[inline] | |
753 | pub fn ln_1p(self) -> f32 { | |
754 | unsafe { cmath::log1pf(self) } | |
755 | } | |
756 | ||
757 | /// Hyperbolic sine function. | |
758 | /// | |
94b46f34 XL |
759 | /// # Examples |
760 | /// | |
c34b1796 | 761 | /// ``` |
ba9703b0 | 762 | /// let e = std::f32::consts::E; |
c34b1796 AL |
763 | /// let x = 1.0f32; |
764 | /// | |
765 | /// let f = x.sinh(); | |
766 | /// // Solving sinh() at 1 gives `(e^2-1)/(2e)` | |
e1599b0c | 767 | /// let g = ((e * e) - 1.0) / (2.0 * e); |
c34b1796 AL |
768 | /// let abs_difference = (f - g).abs(); |
769 | /// | |
770 | /// assert!(abs_difference <= f32::EPSILON); | |
771 | /// ``` | |
60c5eb7d | 772 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
773 | #[stable(feature = "rust1", since = "1.0.0")] |
774 | #[inline] | |
775 | pub fn sinh(self) -> f32 { | |
776 | unsafe { cmath::sinhf(self) } | |
777 | } | |
778 | ||
779 | /// Hyperbolic cosine function. | |
780 | /// | |
94b46f34 XL |
781 | /// # Examples |
782 | /// | |
c34b1796 | 783 | /// ``` |
ba9703b0 | 784 | /// let e = std::f32::consts::E; |
c34b1796 AL |
785 | /// let x = 1.0f32; |
786 | /// let f = x.cosh(); | |
787 | /// // Solving cosh() at 1 gives this result | |
e1599b0c | 788 | /// let g = ((e * e) + 1.0) / (2.0 * e); |
3157f602 | 789 | /// let abs_difference = (f - g).abs(); |
c34b1796 AL |
790 | /// |
791 | /// // Same result | |
792 | /// assert!(abs_difference <= f32::EPSILON); | |
793 | /// ``` | |
60c5eb7d | 794 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
795 | #[stable(feature = "rust1", since = "1.0.0")] |
796 | #[inline] | |
797 | pub fn cosh(self) -> f32 { | |
798 | unsafe { cmath::coshf(self) } | |
799 | } | |
800 | ||
801 | /// Hyperbolic tangent function. | |
802 | /// | |
94b46f34 XL |
803 | /// # Examples |
804 | /// | |
c34b1796 | 805 | /// ``` |
ba9703b0 | 806 | /// let e = std::f32::consts::E; |
c34b1796 AL |
807 | /// let x = 1.0f32; |
808 | /// | |
809 | /// let f = x.tanh(); | |
810 | /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))` | |
e1599b0c | 811 | /// let g = (1.0 - e.powi(-2)) / (1.0 + e.powi(-2)); |
c34b1796 AL |
812 | /// let abs_difference = (f - g).abs(); |
813 | /// | |
814 | /// assert!(abs_difference <= f32::EPSILON); | |
815 | /// ``` | |
60c5eb7d | 816 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
817 | #[stable(feature = "rust1", since = "1.0.0")] |
818 | #[inline] | |
819 | pub fn tanh(self) -> f32 { | |
820 | unsafe { cmath::tanhf(self) } | |
821 | } | |
822 | ||
823 | /// Inverse hyperbolic sine function. | |
824 | /// | |
94b46f34 XL |
825 | /// # Examples |
826 | /// | |
c34b1796 | 827 | /// ``` |
c34b1796 AL |
828 | /// let x = 1.0f32; |
829 | /// let f = x.sinh().asinh(); | |
830 | /// | |
831 | /// let abs_difference = (f - x).abs(); | |
832 | /// | |
833 | /// assert!(abs_difference <= f32::EPSILON); | |
834 | /// ``` | |
60c5eb7d | 835 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
836 | #[stable(feature = "rust1", since = "1.0.0")] |
837 | #[inline] | |
838 | pub fn asinh(self) -> f32 { | |
f035d41b | 839 | (self.abs() + ((self * self) + 1.0).sqrt()).ln().copysign(self) |
c34b1796 AL |
840 | } |
841 | ||
842 | /// Inverse hyperbolic cosine function. | |
843 | /// | |
94b46f34 XL |
844 | /// # Examples |
845 | /// | |
c34b1796 | 846 | /// ``` |
c34b1796 AL |
847 | /// let x = 1.0f32; |
848 | /// let f = x.cosh().acosh(); | |
849 | /// | |
850 | /// let abs_difference = (f - x).abs(); | |
851 | /// | |
852 | /// assert!(abs_difference <= f32::EPSILON); | |
853 | /// ``` | |
60c5eb7d | 854 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
855 | #[stable(feature = "rust1", since = "1.0.0")] |
856 | #[inline] | |
857 | pub fn acosh(self) -> f32 { | |
f9f354fc | 858 | if self < 1.0 { Self::NAN } else { (self + ((self * self) - 1.0).sqrt()).ln() } |
c34b1796 AL |
859 | } |
860 | ||
861 | /// Inverse hyperbolic tangent function. | |
862 | /// | |
94b46f34 XL |
863 | /// # Examples |
864 | /// | |
c34b1796 | 865 | /// ``` |
ba9703b0 | 866 | /// let e = std::f32::consts::E; |
c34b1796 AL |
867 | /// let f = e.tanh().atanh(); |
868 | /// | |
3157f602 | 869 | /// let abs_difference = (f - e).abs(); |
c34b1796 | 870 | /// |
3157f602 | 871 | /// assert!(abs_difference <= 1e-5); |
c34b1796 | 872 | /// ``` |
60c5eb7d | 873 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
874 | #[stable(feature = "rust1", since = "1.0.0")] |
875 | #[inline] | |
876 | pub fn atanh(self) -> f32 { | |
877 | 0.5 * ((2.0 * self) / (1.0 - self)).ln_1p() | |
878 | } | |
879 | } |