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