]>
Commit | Line | Data |
---|---|---|
5869c6ff | 1 | //! Constants specific to the `f64` double-precision floating point type. |
c1a9b12d | 2 | //! |
29967ef6 | 3 | //! *[See also the `f64` primitive type](primitive@f64).* |
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 `f64` 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::f64::{ | |
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 = "f64_runtime"] |
c34b1796 | 32 | impl f64 { |
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_f64; |
c34b1796 | 39 | /// let g = 3.0_f64; |
532ac7d7 | 40 | /// let h = -3.7_f64; |
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 SL |
49 | pub fn floor(self) -> f64 { |
50 | unsafe { intrinsics::floorf64(self) } | |
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_f64; | |
59 | /// let g = 4.0_f64; | |
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 SL |
67 | pub fn ceil(self) -> f64 { |
68 | unsafe { intrinsics::ceilf64(self) } | |
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_f64; | |
78 | /// let g = -3.3_f64; | |
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) -> f64 { |
87 | unsafe { intrinsics::roundf64(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_f64; |
96 | /// let g = 3.0_f64; | |
97 | /// let h = -3.7_f64; | |
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) -> f64 { |
107 | unsafe { intrinsics::truncf64(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_f64; |
116 | /// let y = -3.6_f64; | |
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 < 1e-10); | |
121 | /// assert!(abs_difference_y < 1e-10); | |
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) -> f64 { |
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_f64; |
137 | /// let y = -3.5_f64; | |
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 < 1e-10); | |
143 | /// assert!(abs_difference_y < 1e-10); | |
144 | /// | |
145 | /// assert!(f64::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) -> f64 { |
151 | unsafe { intrinsics::fabsf64(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_f64; |
164 | /// | |
165 | /// assert_eq!(f.signum(), 1.0); | |
166 | /// assert_eq!(f64::NEG_INFINITY.signum(), -1.0); | |
167 | /// | |
168 | /// assert!(f64::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) -> f64 { |
f9f354fc | 174 | if self.is_nan() { Self::NAN } else { 1.0_f64.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_f64; |
188 | /// | |
189 | /// assert_eq!(f.copysign(0.42), 3.5_f64); | |
190 | /// assert_eq!(f.copysign(-0.42), -3.5_f64); | |
191 | /// assert_eq!((-f).copysign(0.42), 3.5_f64); | |
192 | /// assert_eq!((-f).copysign(-0.42), -3.5_f64); | |
193 | /// | |
194 | /// assert!(f64::NAN.copysign(1.0).is_nan()); | |
195 | /// ``` | |
60c5eb7d | 196 | #[must_use = "method returns a new number and does not mutate the original value"] |
532ac7d7 | 197 | #[stable(feature = "copysign", since = "1.35.0")] |
60c5eb7d | 198 | #[inline] |
532ac7d7 XL |
199 | pub fn copysign(self, sign: f64) -> f64 { |
200 | unsafe { intrinsics::copysignf64(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 | /// ``` | |
214 | /// let m = 10.0_f64; | |
215 | /// let x = 4.0_f64; | |
216 | /// let b = 60.0_f64; | |
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 < 1e-10); | |
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: f64, b: f64) -> f64 { |
227 | unsafe { intrinsics::fmaf64(self, a, b) } | |
228 | } | |
85aaf69f | 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: f64 = 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: f64) -> f64 { |
83c7162d XL |
251 | let q = (self / rhs).trunc(); |
252 | if self % rhs < 0.0 { | |
e1599b0c | 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)`. |
83c7162d | 259 | /// |
8faf50e0 | 260 | /// In particular, the return value `r` satisfies `0.0 <= r < rhs.abs()` in |
9fa01778 | 261 | /// most cases. However, due to a floating point round-off error it can |
8faf50e0 XL |
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: f64 = 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!((-f64::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: f64) -> f64 { |
83c7162d | 285 | let r = self % rhs; |
60c5eb7d | 286 | if r < 0.0 { r + rhs.abs() } else { r } |
83c7162d | 287 | } |
c34b1796 | 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 AL |
295 | /// ``` |
296 | /// let x = 2.0_f64; | |
e1599b0c | 297 | /// let abs_difference = (x.powi(2) - (x * x)).abs(); |
c34b1796 AL |
298 | /// |
299 | /// assert!(abs_difference < 1e-10); | |
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) -> f64 { |
305 | unsafe { intrinsics::powif64(self, n) } | |
306 | } | |
c34b1796 | 307 | |
9346a6ac | 308 | /// Raises a number to a floating point power. |
c34b1796 | 309 | /// |
94b46f34 XL |
310 | /// # Examples |
311 | /// | |
c34b1796 AL |
312 | /// ``` |
313 | /// let x = 2.0_f64; | |
e1599b0c | 314 | /// let abs_difference = (x.powf(2.0) - (x * x)).abs(); |
c34b1796 AL |
315 | /// |
316 | /// assert!(abs_difference < 1e-10); | |
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 SL |
321 | pub fn powf(self, n: f64) -> f64 { |
322 | unsafe { intrinsics::powf64(self, n) } | |
323 | } | |
c34b1796 | 324 | |
dfeec247 | 325 | /// Returns the square root of a number. |
c34b1796 | 326 | /// |
136023e0 | 327 | /// Returns NaN if `self` is a negative number other than `-0.0`. |
c34b1796 | 328 | /// |
94b46f34 XL |
329 | /// # Examples |
330 | /// | |
c34b1796 AL |
331 | /// ``` |
332 | /// let positive = 4.0_f64; | |
333 | /// let negative = -4.0_f64; | |
136023e0 | 334 | /// let negative_zero = -0.0_f64; |
c34b1796 AL |
335 | /// |
336 | /// let abs_difference = (positive.sqrt() - 2.0).abs(); | |
337 | /// | |
338 | /// assert!(abs_difference < 1e-10); | |
339 | /// assert!(negative.sqrt().is_nan()); | |
136023e0 | 340 | /// assert!(negative_zero.sqrt() == negative_zero); |
c34b1796 | 341 | /// ``` |
60c5eb7d | 342 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
343 | #[stable(feature = "rust1", since = "1.0.0")] |
344 | #[inline] | |
e9174d1e | 345 | pub fn sqrt(self) -> f64 { |
dfeec247 | 346 | unsafe { intrinsics::sqrtf64(self) } |
e9174d1e | 347 | } |
c34b1796 | 348 | |
c34b1796 AL |
349 | /// Returns `e^(self)`, (the exponential function). |
350 | /// | |
94b46f34 XL |
351 | /// # Examples |
352 | /// | |
c34b1796 AL |
353 | /// ``` |
354 | /// let one = 1.0_f64; | |
355 | /// // e^1 | |
356 | /// let e = one.exp(); | |
357 | /// | |
358 | /// // ln(e) - 1 == 0 | |
359 | /// let abs_difference = (e.ln() - 1.0).abs(); | |
360 | /// | |
361 | /// assert!(abs_difference < 1e-10); | |
362 | /// ``` | |
60c5eb7d | 363 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
364 | #[stable(feature = "rust1", since = "1.0.0")] |
365 | #[inline] | |
e9174d1e SL |
366 | pub fn exp(self) -> f64 { |
367 | unsafe { intrinsics::expf64(self) } | |
368 | } | |
c34b1796 AL |
369 | |
370 | /// Returns `2^(self)`. | |
371 | /// | |
94b46f34 XL |
372 | /// # Examples |
373 | /// | |
c34b1796 AL |
374 | /// ``` |
375 | /// let f = 2.0_f64; | |
376 | /// | |
377 | /// // 2^2 - 4 == 0 | |
378 | /// let abs_difference = (f.exp2() - 4.0).abs(); | |
379 | /// | |
380 | /// assert!(abs_difference < 1e-10); | |
381 | /// ``` | |
60c5eb7d | 382 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
383 | #[stable(feature = "rust1", since = "1.0.0")] |
384 | #[inline] | |
e9174d1e SL |
385 | pub fn exp2(self) -> f64 { |
386 | unsafe { intrinsics::exp2f64(self) } | |
387 | } | |
c34b1796 AL |
388 | |
389 | /// Returns the natural logarithm of the number. | |
390 | /// | |
94b46f34 XL |
391 | /// # Examples |
392 | /// | |
c34b1796 AL |
393 | /// ``` |
394 | /// let one = 1.0_f64; | |
395 | /// // e^1 | |
396 | /// let e = one.exp(); | |
397 | /// | |
398 | /// // ln(e) - 1 == 0 | |
399 | /// let abs_difference = (e.ln() - 1.0).abs(); | |
400 | /// | |
401 | /// assert!(abs_difference < 1e-10); | |
402 | /// ``` | |
60c5eb7d | 403 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
404 | #[stable(feature = "rust1", since = "1.0.0")] |
405 | #[inline] | |
e9174d1e | 406 | pub fn ln(self) -> f64 { |
60c5eb7d | 407 | self.log_wrapper(|n| unsafe { intrinsics::logf64(n) }) |
e9174d1e | 408 | } |
c34b1796 AL |
409 | |
410 | /// Returns the logarithm of the number with respect to an arbitrary base. | |
411 | /// | |
2c00a5a8 XL |
412 | /// The result may not be correctly rounded owing to implementation details; |
413 | /// `self.log2()` can produce more accurate results for base 2, and | |
414 | /// `self.log10()` can produce more accurate results for base 10. | |
c34b1796 | 415 | /// |
94b46f34 XL |
416 | /// # Examples |
417 | /// | |
2c00a5a8 | 418 | /// ``` |
60c5eb7d | 419 | /// let twenty_five = 25.0_f64; |
c34b1796 | 420 | /// |
60c5eb7d XL |
421 | /// // log5(25) - 2 == 0 |
422 | /// let abs_difference = (twenty_five.log(5.0) - 2.0).abs(); | |
c34b1796 | 423 | /// |
2c00a5a8 | 424 | /// assert!(abs_difference < 1e-10); |
c34b1796 | 425 | /// ``` |
60c5eb7d | 426 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
427 | #[stable(feature = "rust1", since = "1.0.0")] |
428 | #[inline] | |
60c5eb7d XL |
429 | pub fn log(self, base: f64) -> f64 { |
430 | self.ln() / base.ln() | |
431 | } | |
c34b1796 AL |
432 | |
433 | /// Returns the base 2 logarithm of the number. | |
434 | /// | |
94b46f34 XL |
435 | /// # Examples |
436 | /// | |
c34b1796 | 437 | /// ``` |
60c5eb7d | 438 | /// let four = 4.0_f64; |
c34b1796 | 439 | /// |
60c5eb7d XL |
440 | /// // log2(4) - 2 == 0 |
441 | /// let abs_difference = (four.log2() - 2.0).abs(); | |
c34b1796 AL |
442 | /// |
443 | /// assert!(abs_difference < 1e-10); | |
444 | /// ``` | |
60c5eb7d | 445 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
446 | #[stable(feature = "rust1", since = "1.0.0")] |
447 | #[inline] | |
e9174d1e | 448 | pub fn log2(self) -> f64 { |
a7813a04 XL |
449 | self.log_wrapper(|n| { |
450 | #[cfg(target_os = "android")] | |
60c5eb7d | 451 | return crate::sys::android::log2f64(n); |
a7813a04 | 452 | #[cfg(not(target_os = "android"))] |
60c5eb7d | 453 | return unsafe { intrinsics::log2f64(n) }; |
a7813a04 | 454 | }) |
e9174d1e | 455 | } |
c34b1796 AL |
456 | |
457 | /// Returns the base 10 logarithm of the number. | |
458 | /// | |
94b46f34 XL |
459 | /// # Examples |
460 | /// | |
c34b1796 | 461 | /// ``` |
60c5eb7d | 462 | /// let hundred = 100.0_f64; |
c34b1796 | 463 | /// |
60c5eb7d XL |
464 | /// // log10(100) - 2 == 0 |
465 | /// let abs_difference = (hundred.log10() - 2.0).abs(); | |
c34b1796 AL |
466 | /// |
467 | /// assert!(abs_difference < 1e-10); | |
468 | /// ``` | |
60c5eb7d | 469 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
470 | #[stable(feature = "rust1", since = "1.0.0")] |
471 | #[inline] | |
e9174d1e | 472 | pub fn log10(self) -> f64 { |
60c5eb7d | 473 | self.log_wrapper(|n| unsafe { intrinsics::log10f64(n) }) |
e9174d1e | 474 | } |
c34b1796 | 475 | |
c34b1796 AL |
476 | /// The positive difference of two numbers. |
477 | /// | |
478 | /// * If `self <= other`: `0:0` | |
479 | /// * Else: `self - other` | |
480 | /// | |
94b46f34 XL |
481 | /// # Examples |
482 | /// | |
c34b1796 AL |
483 | /// ``` |
484 | /// let x = 3.0_f64; | |
485 | /// let y = -3.0_f64; | |
486 | /// | |
487 | /// let abs_difference_x = (x.abs_sub(1.0) - 2.0).abs(); | |
488 | /// let abs_difference_y = (y.abs_sub(1.0) - 0.0).abs(); | |
489 | /// | |
490 | /// assert!(abs_difference_x < 1e-10); | |
491 | /// assert!(abs_difference_y < 1e-10); | |
492 | /// ``` | |
60c5eb7d | 493 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
494 | #[stable(feature = "rust1", since = "1.0.0")] |
495 | #[inline] | |
60c5eb7d XL |
496 | #[rustc_deprecated( |
497 | since = "1.10.0", | |
498 | reason = "you probably meant `(self - other).abs()`: \ | |
499 | this operation is `(self - other).max(0.0)` \ | |
500 | except that `abs_sub` also propagates NaNs (also \ | |
501 | known as `fdim` in C). If you truly need the positive \ | |
502 | difference, consider using that expression or the C function \ | |
503 | `fdim`, depending on how you wish to handle NaN (please consider \ | |
504 | filing an issue describing your use-case too)." | |
505 | )] | |
e1599b0c XL |
506 | pub fn abs_sub(self, other: f64) -> f64 { |
507 | unsafe { cmath::fdim(self, other) } | |
508 | } | |
c34b1796 | 509 | |
6a06907d | 510 | /// Returns the cube root of a number. |
c34b1796 | 511 | /// |
94b46f34 XL |
512 | /// # Examples |
513 | /// | |
c34b1796 AL |
514 | /// ``` |
515 | /// let x = 8.0_f64; | |
516 | /// | |
517 | /// // x^(1/3) - 2 == 0 | |
518 | /// let abs_difference = (x.cbrt() - 2.0).abs(); | |
519 | /// | |
520 | /// assert!(abs_difference < 1e-10); | |
521 | /// ``` | |
60c5eb7d | 522 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
523 | #[stable(feature = "rust1", since = "1.0.0")] |
524 | #[inline] | |
525 | pub fn cbrt(self) -> f64 { | |
526 | unsafe { cmath::cbrt(self) } | |
527 | } | |
528 | ||
9346a6ac | 529 | /// Calculates the length of the hypotenuse of a right-angle triangle given |
c34b1796 AL |
530 | /// legs of length `x` and `y`. |
531 | /// | |
94b46f34 XL |
532 | /// # Examples |
533 | /// | |
c34b1796 AL |
534 | /// ``` |
535 | /// let x = 2.0_f64; | |
536 | /// let y = 3.0_f64; | |
537 | /// | |
538 | /// // sqrt(x^2 + y^2) | |
539 | /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs(); | |
540 | /// | |
541 | /// assert!(abs_difference < 1e-10); | |
542 | /// ``` | |
60c5eb7d | 543 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
544 | #[stable(feature = "rust1", since = "1.0.0")] |
545 | #[inline] | |
546 | pub fn hypot(self, other: f64) -> f64 { | |
547 | unsafe { cmath::hypot(self, other) } | |
548 | } | |
549 | ||
550 | /// Computes the sine of a number (in radians). | |
551 | /// | |
94b46f34 XL |
552 | /// # Examples |
553 | /// | |
c34b1796 | 554 | /// ``` |
ba9703b0 | 555 | /// let x = std::f64::consts::FRAC_PI_2; |
c34b1796 AL |
556 | /// |
557 | /// let abs_difference = (x.sin() - 1.0).abs(); | |
558 | /// | |
559 | /// assert!(abs_difference < 1e-10); | |
560 | /// ``` | |
60c5eb7d | 561 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
562 | #[stable(feature = "rust1", since = "1.0.0")] |
563 | #[inline] | |
564 | pub fn sin(self) -> f64 { | |
565 | unsafe { intrinsics::sinf64(self) } | |
566 | } | |
567 | ||
568 | /// Computes the cosine of a number (in radians). | |
569 | /// | |
94b46f34 XL |
570 | /// # Examples |
571 | /// | |
c34b1796 | 572 | /// ``` |
ba9703b0 | 573 | /// let x = 2.0 * std::f64::consts::PI; |
c34b1796 AL |
574 | /// |
575 | /// let abs_difference = (x.cos() - 1.0).abs(); | |
576 | /// | |
577 | /// assert!(abs_difference < 1e-10); | |
578 | /// ``` | |
60c5eb7d | 579 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
580 | #[stable(feature = "rust1", since = "1.0.0")] |
581 | #[inline] | |
582 | pub fn cos(self) -> f64 { | |
583 | unsafe { intrinsics::cosf64(self) } | |
584 | } | |
585 | ||
586 | /// Computes the tangent of a number (in radians). | |
587 | /// | |
94b46f34 XL |
588 | /// # Examples |
589 | /// | |
c34b1796 | 590 | /// ``` |
ba9703b0 | 591 | /// let x = std::f64::consts::FRAC_PI_4; |
c34b1796 AL |
592 | /// let abs_difference = (x.tan() - 1.0).abs(); |
593 | /// | |
594 | /// assert!(abs_difference < 1e-14); | |
595 | /// ``` | |
60c5eb7d | 596 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
597 | #[stable(feature = "rust1", since = "1.0.0")] |
598 | #[inline] | |
599 | pub fn tan(self) -> f64 { | |
600 | unsafe { cmath::tan(self) } | |
601 | } | |
602 | ||
603 | /// Computes the arcsine of a number. Return value is in radians in | |
604 | /// the range [-pi/2, pi/2] or NaN if the number is outside the range | |
605 | /// [-1, 1]. | |
606 | /// | |
94b46f34 XL |
607 | /// # Examples |
608 | /// | |
c34b1796 | 609 | /// ``` |
ba9703b0 | 610 | /// let f = std::f64::consts::FRAC_PI_2; |
c34b1796 AL |
611 | /// |
612 | /// // asin(sin(pi/2)) | |
ba9703b0 | 613 | /// let abs_difference = (f.sin().asin() - std::f64::consts::FRAC_PI_2).abs(); |
c34b1796 AL |
614 | /// |
615 | /// assert!(abs_difference < 1e-10); | |
616 | /// ``` | |
60c5eb7d | 617 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
618 | #[stable(feature = "rust1", since = "1.0.0")] |
619 | #[inline] | |
620 | pub fn asin(self) -> f64 { | |
621 | unsafe { cmath::asin(self) } | |
622 | } | |
623 | ||
624 | /// Computes the arccosine of a number. Return value is in radians in | |
625 | /// the range [0, pi] or NaN if the number is outside the range | |
626 | /// [-1, 1]. | |
627 | /// | |
94b46f34 XL |
628 | /// # Examples |
629 | /// | |
c34b1796 | 630 | /// ``` |
ba9703b0 | 631 | /// let f = std::f64::consts::FRAC_PI_4; |
c34b1796 AL |
632 | /// |
633 | /// // acos(cos(pi/4)) | |
ba9703b0 | 634 | /// let abs_difference = (f.cos().acos() - std::f64::consts::FRAC_PI_4).abs(); |
c34b1796 AL |
635 | /// |
636 | /// assert!(abs_difference < 1e-10); | |
637 | /// ``` | |
60c5eb7d | 638 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
639 | #[stable(feature = "rust1", since = "1.0.0")] |
640 | #[inline] | |
641 | pub fn acos(self) -> f64 { | |
642 | unsafe { cmath::acos(self) } | |
643 | } | |
644 | ||
645 | /// Computes the arctangent of a number. Return value is in radians in the | |
646 | /// range [-pi/2, pi/2]; | |
647 | /// | |
94b46f34 XL |
648 | /// # Examples |
649 | /// | |
c34b1796 AL |
650 | /// ``` |
651 | /// let f = 1.0_f64; | |
652 | /// | |
653 | /// // atan(tan(1)) | |
654 | /// let abs_difference = (f.tan().atan() - 1.0).abs(); | |
655 | /// | |
656 | /// assert!(abs_difference < 1e-10); | |
657 | /// ``` | |
60c5eb7d | 658 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
659 | #[stable(feature = "rust1", since = "1.0.0")] |
660 | #[inline] | |
661 | pub fn atan(self) -> f64 { | |
662 | unsafe { cmath::atan(self) } | |
663 | } | |
664 | ||
0531ce1d | 665 | /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`) in radians. |
c34b1796 AL |
666 | /// |
667 | /// * `x = 0`, `y = 0`: `0` | |
668 | /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]` | |
669 | /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]` | |
670 | /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)` | |
671 | /// | |
94b46f34 XL |
672 | /// # Examples |
673 | /// | |
c34b1796 | 674 | /// ``` |
0531ce1d XL |
675 | /// // Positive angles measured counter-clockwise |
676 | /// // from positive x axis | |
677 | /// // -pi/4 radians (45 deg clockwise) | |
c34b1796 AL |
678 | /// let x1 = 3.0_f64; |
679 | /// let y1 = -3.0_f64; | |
680 | /// | |
0531ce1d | 681 | /// // 3pi/4 radians (135 deg counter-clockwise) |
c34b1796 AL |
682 | /// let x2 = -3.0_f64; |
683 | /// let y2 = 3.0_f64; | |
684 | /// | |
ba9703b0 XL |
685 | /// let abs_difference_1 = (y1.atan2(x1) - (-std::f64::consts::FRAC_PI_4)).abs(); |
686 | /// let abs_difference_2 = (y2.atan2(x2) - (3.0 * std::f64::consts::FRAC_PI_4)).abs(); | |
c34b1796 AL |
687 | /// |
688 | /// assert!(abs_difference_1 < 1e-10); | |
689 | /// assert!(abs_difference_2 < 1e-10); | |
690 | /// ``` | |
60c5eb7d | 691 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
692 | #[stable(feature = "rust1", since = "1.0.0")] |
693 | #[inline] | |
694 | pub fn atan2(self, other: f64) -> f64 { | |
695 | unsafe { cmath::atan2(self, other) } | |
696 | } | |
697 | ||
698 | /// Simultaneously computes the sine and cosine of the number, `x`. Returns | |
699 | /// `(sin(x), cos(x))`. | |
700 | /// | |
94b46f34 XL |
701 | /// # Examples |
702 | /// | |
c34b1796 | 703 | /// ``` |
ba9703b0 | 704 | /// let x = std::f64::consts::FRAC_PI_4; |
c34b1796 AL |
705 | /// let f = x.sin_cos(); |
706 | /// | |
707 | /// let abs_difference_0 = (f.0 - x.sin()).abs(); | |
708 | /// let abs_difference_1 = (f.1 - x.cos()).abs(); | |
709 | /// | |
710 | /// assert!(abs_difference_0 < 1e-10); | |
a7813a04 | 711 | /// assert!(abs_difference_1 < 1e-10); |
c34b1796 AL |
712 | /// ``` |
713 | #[stable(feature = "rust1", since = "1.0.0")] | |
714 | #[inline] | |
715 | pub fn sin_cos(self) -> (f64, f64) { | |
716 | (self.sin(), self.cos()) | |
717 | } | |
718 | ||
719 | /// Returns `e^(self) - 1` in a way that is accurate even if the | |
720 | /// number is close to zero. | |
721 | /// | |
94b46f34 XL |
722 | /// # Examples |
723 | /// | |
c34b1796 | 724 | /// ``` |
29967ef6 | 725 | /// let x = 1e-16_f64; |
c34b1796 | 726 | /// |
29967ef6 XL |
727 | /// // for very small x, e^x is approximately 1 + x + x^2 / 2 |
728 | /// let approx = x + x * x / 2.0; | |
729 | /// let abs_difference = (x.exp_m1() - approx).abs(); | |
c34b1796 | 730 | /// |
29967ef6 | 731 | /// assert!(abs_difference < 1e-20); |
c34b1796 | 732 | /// ``` |
60c5eb7d | 733 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
734 | #[stable(feature = "rust1", since = "1.0.0")] |
735 | #[inline] | |
736 | pub fn exp_m1(self) -> f64 { | |
737 | unsafe { cmath::expm1(self) } | |
738 | } | |
739 | ||
740 | /// Returns `ln(1+n)` (natural logarithm) more accurately than if | |
741 | /// the operations were performed separately. | |
742 | /// | |
94b46f34 XL |
743 | /// # Examples |
744 | /// | |
c34b1796 | 745 | /// ``` |
29967ef6 | 746 | /// let x = 1e-16_f64; |
c34b1796 | 747 | /// |
29967ef6 XL |
748 | /// // for very small x, ln(1 + x) is approximately x - x^2 / 2 |
749 | /// let approx = x - x * x / 2.0; | |
750 | /// let abs_difference = (x.ln_1p() - approx).abs(); | |
c34b1796 | 751 | /// |
29967ef6 | 752 | /// assert!(abs_difference < 1e-20); |
c34b1796 | 753 | /// ``` |
60c5eb7d | 754 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
755 | #[stable(feature = "rust1", since = "1.0.0")] |
756 | #[inline] | |
757 | pub fn ln_1p(self) -> f64 { | |
758 | unsafe { cmath::log1p(self) } | |
759 | } | |
760 | ||
761 | /// Hyperbolic sine function. | |
762 | /// | |
94b46f34 XL |
763 | /// # Examples |
764 | /// | |
c34b1796 | 765 | /// ``` |
ba9703b0 | 766 | /// let e = std::f64::consts::E; |
c34b1796 AL |
767 | /// let x = 1.0_f64; |
768 | /// | |
769 | /// let f = x.sinh(); | |
770 | /// // Solving sinh() at 1 gives `(e^2-1)/(2e)` | |
e1599b0c | 771 | /// let g = ((e * e) - 1.0) / (2.0 * e); |
c34b1796 AL |
772 | /// let abs_difference = (f - g).abs(); |
773 | /// | |
774 | /// assert!(abs_difference < 1e-10); | |
775 | /// ``` | |
60c5eb7d | 776 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
777 | #[stable(feature = "rust1", since = "1.0.0")] |
778 | #[inline] | |
779 | pub fn sinh(self) -> f64 { | |
780 | unsafe { cmath::sinh(self) } | |
781 | } | |
782 | ||
783 | /// Hyperbolic cosine function. | |
784 | /// | |
94b46f34 XL |
785 | /// # Examples |
786 | /// | |
c34b1796 | 787 | /// ``` |
ba9703b0 | 788 | /// let e = std::f64::consts::E; |
c34b1796 AL |
789 | /// let x = 1.0_f64; |
790 | /// let f = x.cosh(); | |
791 | /// // Solving cosh() at 1 gives this result | |
e1599b0c | 792 | /// let g = ((e * e) + 1.0) / (2.0 * e); |
c34b1796 AL |
793 | /// let abs_difference = (f - g).abs(); |
794 | /// | |
795 | /// // Same result | |
796 | /// assert!(abs_difference < 1.0e-10); | |
797 | /// ``` | |
60c5eb7d | 798 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
799 | #[stable(feature = "rust1", since = "1.0.0")] |
800 | #[inline] | |
801 | pub fn cosh(self) -> f64 { | |
802 | unsafe { cmath::cosh(self) } | |
803 | } | |
804 | ||
805 | /// Hyperbolic tangent function. | |
806 | /// | |
94b46f34 XL |
807 | /// # Examples |
808 | /// | |
c34b1796 | 809 | /// ``` |
ba9703b0 | 810 | /// let e = std::f64::consts::E; |
c34b1796 AL |
811 | /// let x = 1.0_f64; |
812 | /// | |
813 | /// let f = x.tanh(); | |
814 | /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))` | |
e1599b0c | 815 | /// let g = (1.0 - e.powi(-2)) / (1.0 + e.powi(-2)); |
c34b1796 AL |
816 | /// let abs_difference = (f - g).abs(); |
817 | /// | |
818 | /// assert!(abs_difference < 1.0e-10); | |
819 | /// ``` | |
60c5eb7d | 820 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
821 | #[stable(feature = "rust1", since = "1.0.0")] |
822 | #[inline] | |
823 | pub fn tanh(self) -> f64 { | |
824 | unsafe { cmath::tanh(self) } | |
825 | } | |
826 | ||
827 | /// Inverse hyperbolic sine function. | |
828 | /// | |
94b46f34 XL |
829 | /// # Examples |
830 | /// | |
c34b1796 AL |
831 | /// ``` |
832 | /// let x = 1.0_f64; | |
833 | /// let f = x.sinh().asinh(); | |
834 | /// | |
835 | /// let abs_difference = (f - x).abs(); | |
836 | /// | |
837 | /// assert!(abs_difference < 1.0e-10); | |
838 | /// ``` | |
60c5eb7d | 839 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
840 | #[stable(feature = "rust1", since = "1.0.0")] |
841 | #[inline] | |
842 | pub fn asinh(self) -> f64 { | |
f035d41b | 843 | (self.abs() + ((self * self) + 1.0).sqrt()).ln().copysign(self) |
c34b1796 AL |
844 | } |
845 | ||
846 | /// Inverse hyperbolic cosine function. | |
847 | /// | |
94b46f34 XL |
848 | /// # Examples |
849 | /// | |
c34b1796 AL |
850 | /// ``` |
851 | /// let x = 1.0_f64; | |
852 | /// let f = x.cosh().acosh(); | |
853 | /// | |
854 | /// let abs_difference = (f - x).abs(); | |
855 | /// | |
856 | /// assert!(abs_difference < 1.0e-10); | |
857 | /// ``` | |
60c5eb7d | 858 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
859 | #[stable(feature = "rust1", since = "1.0.0")] |
860 | #[inline] | |
861 | pub fn acosh(self) -> f64 { | |
f9f354fc | 862 | if self < 1.0 { Self::NAN } else { (self + ((self * self) - 1.0).sqrt()).ln() } |
c34b1796 AL |
863 | } |
864 | ||
865 | /// Inverse hyperbolic tangent function. | |
866 | /// | |
94b46f34 XL |
867 | /// # Examples |
868 | /// | |
c34b1796 | 869 | /// ``` |
ba9703b0 | 870 | /// let e = std::f64::consts::E; |
c34b1796 AL |
871 | /// let f = e.tanh().atanh(); |
872 | /// | |
873 | /// let abs_difference = (f - e).abs(); | |
874 | /// | |
875 | /// assert!(abs_difference < 1.0e-10); | |
876 | /// ``` | |
60c5eb7d | 877 | #[must_use = "method returns a new number and does not mutate the original value"] |
c34b1796 AL |
878 | #[stable(feature = "rust1", since = "1.0.0")] |
879 | #[inline] | |
880 | pub fn atanh(self) -> f64 { | |
881 | 0.5 * ((2.0 * self) / (1.0 - self)).ln_1p() | |
882 | } | |
7453a54e | 883 | |
136023e0 XL |
884 | /// Linear interpolation between `start` and `end`. |
885 | /// | |
886 | /// This enables linear interpolation between `start` and `end`, where start is represented by | |
887 | /// `self == 0.0` and `end` is represented by `self == 1.0`. This is the basis of all | |
888 | /// "transition", "easing", or "step" functions; if you change `self` from 0.0 to 1.0 | |
889 | /// at a given rate, the result will change from `start` to `end` at a similar rate. | |
890 | /// | |
891 | /// Values below 0.0 or above 1.0 are allowed, allowing you to extrapolate values outside the | |
892 | /// range from `start` to `end`. This also is useful for transition functions which might | |
893 | /// move slightly past the end or start for a desired effect. Mathematically, the values | |
894 | /// returned are equivalent to `start + self * (end - start)`, although we make a few specific | |
895 | /// guarantees that are useful specifically to linear interpolation. | |
896 | /// | |
897 | /// These guarantees are: | |
898 | /// | |
899 | /// * If `start` and `end` are [finite], the value at 0.0 is always `start` and the | |
900 | /// value at 1.0 is always `end`. (exactness) | |
901 | /// * If `start` and `end` are [finite], the values will always move in the direction from | |
902 | /// `start` to `end` (monotonicity) | |
903 | /// * If `self` is [finite] and `start == end`, the value at any point will always be | |
904 | /// `start == end`. (consistency) | |
905 | /// | |
906 | /// [finite]: #method.is_finite | |
907 | #[must_use = "method returns a new number and does not mutate the original value"] | |
908 | #[unstable(feature = "float_interpolation", issue = "86269")] | |
909 | pub fn lerp(self, start: f64, end: f64) -> f64 { | |
910 | // consistent | |
911 | if start == end { | |
912 | start | |
913 | ||
914 | // exact/monotonic | |
915 | } else { | |
916 | self.mul_add(end, (-self).mul_add(start, start)) | |
917 | } | |
918 | } | |
919 | ||
7453a54e | 920 | // Solaris/Illumos requires a wrapper around log, log2, and log10 functions |
0731742a | 921 | // because of their non-standard behavior (e.g., log(-n) returns -Inf instead |
7453a54e SL |
922 | // of expected NaN). |
923 | fn log_wrapper<F: Fn(f64) -> f64>(self, log_fn: F) -> f64 { | |
ba9703b0 | 924 | if !cfg!(any(target_os = "solaris", target_os = "illumos")) { |
7453a54e | 925 | log_fn(self) |
29967ef6 XL |
926 | } else if self.is_finite() { |
927 | if self > 0.0 { | |
928 | log_fn(self) | |
929 | } else if self == 0.0 { | |
930 | Self::NEG_INFINITY // log(0) = -Inf | |
7453a54e | 931 | } else { |
29967ef6 | 932 | Self::NAN // log(-n) = NaN |
7453a54e | 933 | } |
29967ef6 XL |
934 | } else if self.is_nan() { |
935 | self // log(NaN) = NaN | |
936 | } else if self > 0.0 { | |
937 | self // log(Inf) = Inf | |
938 | } else { | |
939 | Self::NAN // log(-Inf) = NaN | |
7453a54e SL |
940 | } |
941 | } | |
c34b1796 | 942 | } |