std/f64.rs
1//! Constants for the `f64` double-precision floating point type.
2//!
3//! *[See also the `f64` primitive type](primitive@f64).*
4//!
5//! Mathematically significant numbers are provided in the `consts` sub-module.
6//!
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.
11
12#![stable(feature = "rust1", since = "1.0.0")]
13#![allow(missing_docs)]
14
15#[stable(feature = "rust1", since = "1.0.0")]
16#[allow(deprecated, deprecated_in_future)]
17pub use core::f64::{
18 DIGITS, EPSILON, INFINITY, MANTISSA_DIGITS, MAX, MAX_10_EXP, MAX_EXP, MIN, MIN_10_EXP, MIN_EXP,
19 MIN_POSITIVE, NAN, NEG_INFINITY, RADIX, consts,
20};
21
22#[cfg(not(test))]
23use crate::intrinsics;
24#[cfg(not(test))]
25use crate::sys::cmath;
26
27#[cfg(not(test))]
28impl f64 {
29 /// Returns the largest integer less than or equal to `self`.
30 ///
31 /// This function always returns the precise result.
32 ///
33 /// # Examples
34 ///
35 /// ```
36 /// let f = 3.7_f64;
37 /// let g = 3.0_f64;
38 /// let h = -3.7_f64;
39 ///
40 /// assert_eq!(f.floor(), 3.0);
41 /// assert_eq!(g.floor(), 3.0);
42 /// assert_eq!(h.floor(), -4.0);
43 /// ```
44 #[rustc_allow_incoherent_impl]
45 #[must_use = "method returns a new number and does not mutate the original value"]
46 #[stable(feature = "rust1", since = "1.0.0")]
47 #[inline]
48 pub fn floor(self) -> f64 {
49 unsafe { intrinsics::floorf64(self) }
50 }
51
52 /// Returns the smallest integer greater than or equal to `self`.
53 ///
54 /// This function always returns the precise result.
55 ///
56 /// # Examples
57 ///
58 /// ```
59 /// let f = 3.01_f64;
60 /// let g = 4.0_f64;
61 ///
62 /// assert_eq!(f.ceil(), 4.0);
63 /// assert_eq!(g.ceil(), 4.0);
64 /// ```
65 #[doc(alias = "ceiling")]
66 #[rustc_allow_incoherent_impl]
67 #[must_use = "method returns a new number and does not mutate the original value"]
68 #[stable(feature = "rust1", since = "1.0.0")]
69 #[inline]
70 pub fn ceil(self) -> f64 {
71 unsafe { intrinsics::ceilf64(self) }
72 }
73
74 /// Returns the nearest integer to `self`. If a value is half-way between two
75 /// integers, round away from `0.0`.
76 ///
77 /// This function always returns the precise result.
78 ///
79 /// # Examples
80 ///
81 /// ```
82 /// let f = 3.3_f64;
83 /// let g = -3.3_f64;
84 /// let h = -3.7_f64;
85 /// let i = 3.5_f64;
86 /// let j = 4.5_f64;
87 ///
88 /// assert_eq!(f.round(), 3.0);
89 /// assert_eq!(g.round(), -3.0);
90 /// assert_eq!(h.round(), -4.0);
91 /// assert_eq!(i.round(), 4.0);
92 /// assert_eq!(j.round(), 5.0);
93 /// ```
94 #[rustc_allow_incoherent_impl]
95 #[must_use = "method returns a new number and does not mutate the original value"]
96 #[stable(feature = "rust1", since = "1.0.0")]
97 #[inline]
98 pub fn round(self) -> f64 {
99 unsafe { intrinsics::roundf64(self) }
100 }
101
102 /// Returns the nearest integer to a number. Rounds half-way cases to the number
103 /// with an even least significant digit.
104 ///
105 /// This function always returns the precise result.
106 ///
107 /// # Examples
108 ///
109 /// ```
110 /// let f = 3.3_f64;
111 /// let g = -3.3_f64;
112 /// let h = 3.5_f64;
113 /// let i = 4.5_f64;
114 ///
115 /// assert_eq!(f.round_ties_even(), 3.0);
116 /// assert_eq!(g.round_ties_even(), -3.0);
117 /// assert_eq!(h.round_ties_even(), 4.0);
118 /// assert_eq!(i.round_ties_even(), 4.0);
119 /// ```
120 #[rustc_allow_incoherent_impl]
121 #[must_use = "method returns a new number and does not mutate the original value"]
122 #[stable(feature = "round_ties_even", since = "1.77.0")]
123 #[inline]
124 pub fn round_ties_even(self) -> f64 {
125 unsafe { intrinsics::rintf64(self) }
126 }
127
128 /// Returns the integer part of `self`.
129 /// This means that non-integer numbers are always truncated towards zero.
130 ///
131 /// This function always returns the precise result.
132 ///
133 /// # Examples
134 ///
135 /// ```
136 /// let f = 3.7_f64;
137 /// let g = 3.0_f64;
138 /// let h = -3.7_f64;
139 ///
140 /// assert_eq!(f.trunc(), 3.0);
141 /// assert_eq!(g.trunc(), 3.0);
142 /// assert_eq!(h.trunc(), -3.0);
143 /// ```
144 #[doc(alias = "truncate")]
145 #[rustc_allow_incoherent_impl]
146 #[must_use = "method returns a new number and does not mutate the original value"]
147 #[stable(feature = "rust1", since = "1.0.0")]
148 #[inline]
149 pub fn trunc(self) -> f64 {
150 unsafe { intrinsics::truncf64(self) }
151 }
152
153 /// Returns the fractional part of `self`.
154 ///
155 /// This function always returns the precise result.
156 ///
157 /// # Examples
158 ///
159 /// ```
160 /// let x = 3.6_f64;
161 /// let y = -3.6_f64;
162 /// let abs_difference_x = (x.fract() - 0.6).abs();
163 /// let abs_difference_y = (y.fract() - (-0.6)).abs();
164 ///
165 /// assert!(abs_difference_x < 1e-10);
166 /// assert!(abs_difference_y < 1e-10);
167 /// ```
168 #[rustc_allow_incoherent_impl]
169 #[must_use = "method returns a new number and does not mutate the original value"]
170 #[stable(feature = "rust1", since = "1.0.0")]
171 #[inline]
172 pub fn fract(self) -> f64 {
173 self - self.trunc()
174 }
175
176 /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
177 /// error, yielding a more accurate result than an unfused multiply-add.
178 ///
179 /// Using `mul_add` *may* be more performant than an unfused multiply-add if
180 /// the target architecture has a dedicated `fma` CPU instruction. However,
181 /// this is not always true, and will be heavily dependant on designing
182 /// algorithms with specific target hardware in mind.
183 ///
184 /// # Precision
185 ///
186 /// The result of this operation is guaranteed to be the rounded
187 /// infinite-precision result. It is specified by IEEE 754 as
188 /// `fusedMultiplyAdd` and guaranteed not to change.
189 ///
190 /// # Examples
191 ///
192 /// ```
193 /// let m = 10.0_f64;
194 /// let x = 4.0_f64;
195 /// let b = 60.0_f64;
196 ///
197 /// assert_eq!(m.mul_add(x, b), 100.0);
198 /// assert_eq!(m * x + b, 100.0);
199 ///
200 /// let one_plus_eps = 1.0_f64 + f64::EPSILON;
201 /// let one_minus_eps = 1.0_f64 - f64::EPSILON;
202 /// let minus_one = -1.0_f64;
203 ///
204 /// // The exact result (1 + eps) * (1 - eps) = 1 - eps * eps.
205 /// assert_eq!(one_plus_eps.mul_add(one_minus_eps, minus_one), -f64::EPSILON * f64::EPSILON);
206 /// // Different rounding with the non-fused multiply and add.
207 /// assert_eq!(one_plus_eps * one_minus_eps + minus_one, 0.0);
208 /// ```
209 #[rustc_allow_incoherent_impl]
210 #[doc(alias = "fma", alias = "fusedMultiplyAdd")]
211 #[must_use = "method returns a new number and does not mutate the original value"]
212 #[stable(feature = "rust1", since = "1.0.0")]
213 #[inline]
214 pub fn mul_add(self, a: f64, b: f64) -> f64 {
215 unsafe { intrinsics::fmaf64(self, a, b) }
216 }
217
218 /// Calculates Euclidean division, the matching method for `rem_euclid`.
219 ///
220 /// This computes the integer `n` such that
221 /// `self = n * rhs + self.rem_euclid(rhs)`.
222 /// In other words, the result is `self / rhs` rounded to the integer `n`
223 /// such that `self >= n * rhs`.
224 ///
225 /// # Precision
226 ///
227 /// The result of this operation is guaranteed to be the rounded
228 /// infinite-precision result.
229 ///
230 /// # Examples
231 ///
232 /// ```
233 /// let a: f64 = 7.0;
234 /// let b = 4.0;
235 /// assert_eq!(a.div_euclid(b), 1.0); // 7.0 > 4.0 * 1.0
236 /// assert_eq!((-a).div_euclid(b), -2.0); // -7.0 >= 4.0 * -2.0
237 /// assert_eq!(a.div_euclid(-b), -1.0); // 7.0 >= -4.0 * -1.0
238 /// assert_eq!((-a).div_euclid(-b), 2.0); // -7.0 >= -4.0 * 2.0
239 /// ```
240 #[rustc_allow_incoherent_impl]
241 #[must_use = "method returns a new number and does not mutate the original value"]
242 #[inline]
243 #[stable(feature = "euclidean_division", since = "1.38.0")]
244 pub fn div_euclid(self, rhs: f64) -> f64 {
245 let q = (self / rhs).trunc();
246 if self % rhs < 0.0 {
247 return if rhs > 0.0 { q - 1.0 } else { q + 1.0 };
248 }
249 q
250 }
251
252 /// Calculates the least nonnegative remainder of `self (mod rhs)`.
253 ///
254 /// In particular, the return value `r` satisfies `0.0 <= r < rhs.abs()` in
255 /// most cases. However, due to a floating point round-off error it can
256 /// result in `r == rhs.abs()`, violating the mathematical definition, if
257 /// `self` is much smaller than `rhs.abs()` in magnitude and `self < 0.0`.
258 /// This result is not an element of the function's codomain, but it is the
259 /// closest floating point number in the real numbers and thus fulfills the
260 /// property `self == self.div_euclid(rhs) * rhs + self.rem_euclid(rhs)`
261 /// approximately.
262 ///
263 /// # Precision
264 ///
265 /// The result of this operation is guaranteed to be the rounded
266 /// infinite-precision result.
267 ///
268 /// # Examples
269 ///
270 /// ```
271 /// let a: f64 = 7.0;
272 /// let b = 4.0;
273 /// assert_eq!(a.rem_euclid(b), 3.0);
274 /// assert_eq!((-a).rem_euclid(b), 1.0);
275 /// assert_eq!(a.rem_euclid(-b), 3.0);
276 /// assert_eq!((-a).rem_euclid(-b), 1.0);
277 /// // limitation due to round-off error
278 /// assert!((-f64::EPSILON).rem_euclid(3.0) != 0.0);
279 /// ```
280 #[doc(alias = "modulo", alias = "mod")]
281 #[rustc_allow_incoherent_impl]
282 #[must_use = "method returns a new number and does not mutate the original value"]
283 #[inline]
284 #[stable(feature = "euclidean_division", since = "1.38.0")]
285 pub fn rem_euclid(self, rhs: f64) -> f64 {
286 let r = self % rhs;
287 if r < 0.0 { r + rhs.abs() } else { r }
288 }
289
290 /// Raises a number to an integer power.
291 ///
292 /// Using this function is generally faster than using `powf`.
293 /// It might have a different sequence of rounding operations than `powf`,
294 /// so the results are not guaranteed to agree.
295 ///
296 /// # Unspecified precision
297 ///
298 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
299 /// can even differ within the same execution from one invocation to the next.
300 ///
301 /// # Examples
302 ///
303 /// ```
304 /// let x = 2.0_f64;
305 /// let abs_difference = (x.powi(2) - (x * x)).abs();
306 /// assert!(abs_difference <= f64::EPSILON);
307 ///
308 /// assert_eq!(f64::powi(f64::NAN, 0), 1.0);
309 /// ```
310 #[rustc_allow_incoherent_impl]
311 #[must_use = "method returns a new number and does not mutate the original value"]
312 #[stable(feature = "rust1", since = "1.0.0")]
313 #[inline]
314 pub fn powi(self, n: i32) -> f64 {
315 unsafe { intrinsics::powif64(self, n) }
316 }
317
318 /// Raises a number to a floating point power.
319 ///
320 /// # Unspecified precision
321 ///
322 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
323 /// can even differ within the same execution from one invocation to the next.
324 ///
325 /// # Examples
326 ///
327 /// ```
328 /// let x = 2.0_f64;
329 /// let abs_difference = (x.powf(2.0) - (x * x)).abs();
330 /// assert!(abs_difference <= f64::EPSILON);
331 ///
332 /// assert_eq!(f64::powf(1.0, f64::NAN), 1.0);
333 /// assert_eq!(f64::powf(f64::NAN, 0.0), 1.0);
334 /// ```
335 #[rustc_allow_incoherent_impl]
336 #[must_use = "method returns a new number and does not mutate the original value"]
337 #[stable(feature = "rust1", since = "1.0.0")]
338 #[inline]
339 pub fn powf(self, n: f64) -> f64 {
340 unsafe { intrinsics::powf64(self, n) }
341 }
342
343 /// Returns the square root of a number.
344 ///
345 /// Returns NaN if `self` is a negative number other than `-0.0`.
346 ///
347 /// # Precision
348 ///
349 /// The result of this operation is guaranteed to be the rounded
350 /// infinite-precision result. It is specified by IEEE 754 as `squareRoot`
351 /// and guaranteed not to change.
352 ///
353 /// # Examples
354 ///
355 /// ```
356 /// let positive = 4.0_f64;
357 /// let negative = -4.0_f64;
358 /// let negative_zero = -0.0_f64;
359 ///
360 /// assert_eq!(positive.sqrt(), 2.0);
361 /// assert!(negative.sqrt().is_nan());
362 /// assert!(negative_zero.sqrt() == negative_zero);
363 /// ```
364 #[doc(alias = "squareRoot")]
365 #[rustc_allow_incoherent_impl]
366 #[must_use = "method returns a new number and does not mutate the original value"]
367 #[stable(feature = "rust1", since = "1.0.0")]
368 #[inline]
369 pub fn sqrt(self) -> f64 {
370 unsafe { intrinsics::sqrtf64(self) }
371 }
372
373 /// Returns `e^(self)`, (the exponential function).
374 ///
375 /// # Unspecified precision
376 ///
377 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
378 /// can even differ within the same execution from one invocation to the next.
379 ///
380 /// # Examples
381 ///
382 /// ```
383 /// let one = 1.0_f64;
384 /// // e^1
385 /// let e = one.exp();
386 ///
387 /// // ln(e) - 1 == 0
388 /// let abs_difference = (e.ln() - 1.0).abs();
389 ///
390 /// assert!(abs_difference < 1e-10);
391 /// ```
392 #[rustc_allow_incoherent_impl]
393 #[must_use = "method returns a new number and does not mutate the original value"]
394 #[stable(feature = "rust1", since = "1.0.0")]
395 #[inline]
396 pub fn exp(self) -> f64 {
397 unsafe { intrinsics::expf64(self) }
398 }
399
400 /// Returns `2^(self)`.
401 ///
402 /// # Unspecified precision
403 ///
404 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
405 /// can even differ within the same execution from one invocation to the next.
406 ///
407 /// # Examples
408 ///
409 /// ```
410 /// let f = 2.0_f64;
411 ///
412 /// // 2^2 - 4 == 0
413 /// let abs_difference = (f.exp2() - 4.0).abs();
414 ///
415 /// assert!(abs_difference < 1e-10);
416 /// ```
417 #[rustc_allow_incoherent_impl]
418 #[must_use = "method returns a new number and does not mutate the original value"]
419 #[stable(feature = "rust1", since = "1.0.0")]
420 #[inline]
421 pub fn exp2(self) -> f64 {
422 unsafe { intrinsics::exp2f64(self) }
423 }
424
425 /// Returns the natural logarithm of the number.
426 ///
427 /// # Unspecified precision
428 ///
429 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
430 /// can even differ within the same execution from one invocation to the next.
431 ///
432 /// # Examples
433 ///
434 /// ```
435 /// let one = 1.0_f64;
436 /// // e^1
437 /// let e = one.exp();
438 ///
439 /// // ln(e) - 1 == 0
440 /// let abs_difference = (e.ln() - 1.0).abs();
441 ///
442 /// assert!(abs_difference < 1e-10);
443 /// ```
444 #[rustc_allow_incoherent_impl]
445 #[must_use = "method returns a new number and does not mutate the original value"]
446 #[stable(feature = "rust1", since = "1.0.0")]
447 #[inline]
448 pub fn ln(self) -> f64 {
449 unsafe { intrinsics::logf64(self) }
450 }
451
452 /// Returns the logarithm of the number with respect to an arbitrary base.
453 ///
454 /// The result might not be correctly rounded owing to implementation details;
455 /// `self.log2()` can produce more accurate results for base 2, and
456 /// `self.log10()` can produce more accurate results for base 10.
457 ///
458 /// # Unspecified precision
459 ///
460 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
461 /// can even differ within the same execution from one invocation to the next.
462 ///
463 /// # Examples
464 ///
465 /// ```
466 /// let twenty_five = 25.0_f64;
467 ///
468 /// // log5(25) - 2 == 0
469 /// let abs_difference = (twenty_five.log(5.0) - 2.0).abs();
470 ///
471 /// assert!(abs_difference < 1e-10);
472 /// ```
473 #[rustc_allow_incoherent_impl]
474 #[must_use = "method returns a new number and does not mutate the original value"]
475 #[stable(feature = "rust1", since = "1.0.0")]
476 #[inline]
477 pub fn log(self, base: f64) -> f64 {
478 self.ln() / base.ln()
479 }
480
481 /// Returns the base 2 logarithm of the number.
482 ///
483 /// # Unspecified precision
484 ///
485 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
486 /// can even differ within the same execution from one invocation to the next.
487 ///
488 /// # Examples
489 ///
490 /// ```
491 /// let four = 4.0_f64;
492 ///
493 /// // log2(4) - 2 == 0
494 /// let abs_difference = (four.log2() - 2.0).abs();
495 ///
496 /// assert!(abs_difference < 1e-10);
497 /// ```
498 #[rustc_allow_incoherent_impl]
499 #[must_use = "method returns a new number and does not mutate the original value"]
500 #[stable(feature = "rust1", since = "1.0.0")]
501 #[inline]
502 pub fn log2(self) -> f64 {
503 unsafe { intrinsics::log2f64(self) }
504 }
505
506 /// Returns the base 10 logarithm of the number.
507 ///
508 /// # Unspecified precision
509 ///
510 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
511 /// can even differ within the same execution from one invocation to the next.
512 ///
513 /// # Examples
514 ///
515 /// ```
516 /// let hundred = 100.0_f64;
517 ///
518 /// // log10(100) - 2 == 0
519 /// let abs_difference = (hundred.log10() - 2.0).abs();
520 ///
521 /// assert!(abs_difference < 1e-10);
522 /// ```
523 #[rustc_allow_incoherent_impl]
524 #[must_use = "method returns a new number and does not mutate the original value"]
525 #[stable(feature = "rust1", since = "1.0.0")]
526 #[inline]
527 pub fn log10(self) -> f64 {
528 unsafe { intrinsics::log10f64(self) }
529 }
530
531 /// The positive difference of two numbers.
532 ///
533 /// * If `self <= other`: `0.0`
534 /// * Else: `self - other`
535 ///
536 /// # Unspecified precision
537 ///
538 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
539 /// can even differ within the same execution from one invocation to the next.
540 /// This function currently corresponds to the `fdim` from libc on Unix and
541 /// Windows. Note that this might change in the future.
542 ///
543 /// # Examples
544 ///
545 /// ```
546 /// let x = 3.0_f64;
547 /// let y = -3.0_f64;
548 ///
549 /// let abs_difference_x = (x.abs_sub(1.0) - 2.0).abs();
550 /// let abs_difference_y = (y.abs_sub(1.0) - 0.0).abs();
551 ///
552 /// assert!(abs_difference_x < 1e-10);
553 /// assert!(abs_difference_y < 1e-10);
554 /// ```
555 #[rustc_allow_incoherent_impl]
556 #[must_use = "method returns a new number and does not mutate the original value"]
557 #[stable(feature = "rust1", since = "1.0.0")]
558 #[inline]
559 #[deprecated(
560 since = "1.10.0",
561 note = "you probably meant `(self - other).abs()`: \
562 this operation is `(self - other).max(0.0)` \
563 except that `abs_sub` also propagates NaNs (also \
564 known as `fdim` in C). If you truly need the positive \
565 difference, consider using that expression or the C function \
566 `fdim`, depending on how you wish to handle NaN (please consider \
567 filing an issue describing your use-case too)."
568 )]
569 pub fn abs_sub(self, other: f64) -> f64 {
570 unsafe { cmath::fdim(self, other) }
571 }
572
573 /// Returns the cube root of a number.
574 ///
575 /// # Unspecified precision
576 ///
577 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
578 /// can even differ within the same execution from one invocation to the next.
579 /// This function currently corresponds to the `cbrt` from libc on Unix and
580 /// Windows. Note that this might change in the future.
581 ///
582 /// # Examples
583 ///
584 /// ```
585 /// let x = 8.0_f64;
586 ///
587 /// // x^(1/3) - 2 == 0
588 /// let abs_difference = (x.cbrt() - 2.0).abs();
589 ///
590 /// assert!(abs_difference < 1e-10);
591 /// ```
592 #[rustc_allow_incoherent_impl]
593 #[must_use = "method returns a new number and does not mutate the original value"]
594 #[stable(feature = "rust1", since = "1.0.0")]
595 #[inline]
596 pub fn cbrt(self) -> f64 {
597 unsafe { cmath::cbrt(self) }
598 }
599
600 /// Compute the distance between the origin and a point (`x`, `y`) on the
601 /// Euclidean plane. Equivalently, compute the length of the hypotenuse of a
602 /// right-angle triangle with other sides having length `x.abs()` and
603 /// `y.abs()`.
604 ///
605 /// # Unspecified precision
606 ///
607 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
608 /// can even differ within the same execution from one invocation to the next.
609 /// This function currently corresponds to the `hypot` from libc on Unix
610 /// and Windows. Note that this might change in the future.
611 ///
612 /// # Examples
613 ///
614 /// ```
615 /// let x = 2.0_f64;
616 /// let y = 3.0_f64;
617 ///
618 /// // sqrt(x^2 + y^2)
619 /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs();
620 ///
621 /// assert!(abs_difference < 1e-10);
622 /// ```
623 #[rustc_allow_incoherent_impl]
624 #[must_use = "method returns a new number and does not mutate the original value"]
625 #[stable(feature = "rust1", since = "1.0.0")]
626 #[inline]
627 pub fn hypot(self, other: f64) -> f64 {
628 unsafe { cmath::hypot(self, other) }
629 }
630
631 /// Computes the sine of a number (in radians).
632 ///
633 /// # Unspecified precision
634 ///
635 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
636 /// can even differ within the same execution from one invocation to the next.
637 ///
638 /// # Examples
639 ///
640 /// ```
641 /// let x = std::f64::consts::FRAC_PI_2;
642 ///
643 /// let abs_difference = (x.sin() - 1.0).abs();
644 ///
645 /// assert!(abs_difference < 1e-10);
646 /// ```
647 #[rustc_allow_incoherent_impl]
648 #[must_use = "method returns a new number and does not mutate the original value"]
649 #[stable(feature = "rust1", since = "1.0.0")]
650 #[inline]
651 pub fn sin(self) -> f64 {
652 unsafe { intrinsics::sinf64(self) }
653 }
654
655 /// Computes the cosine of a number (in radians).
656 ///
657 /// # Unspecified precision
658 ///
659 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
660 /// can even differ within the same execution from one invocation to the next.
661 ///
662 /// # Examples
663 ///
664 /// ```
665 /// let x = 2.0 * std::f64::consts::PI;
666 ///
667 /// let abs_difference = (x.cos() - 1.0).abs();
668 ///
669 /// assert!(abs_difference < 1e-10);
670 /// ```
671 #[rustc_allow_incoherent_impl]
672 #[must_use = "method returns a new number and does not mutate the original value"]
673 #[stable(feature = "rust1", since = "1.0.0")]
674 #[inline]
675 pub fn cos(self) -> f64 {
676 unsafe { intrinsics::cosf64(self) }
677 }
678
679 /// Computes the tangent of a number (in radians).
680 ///
681 /// # Unspecified precision
682 ///
683 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
684 /// can even differ within the same execution from one invocation to the next.
685 /// This function currently corresponds to the `tan` from libc on Unix and
686 /// Windows. Note that this might change in the future.
687 ///
688 /// # Examples
689 ///
690 /// ```
691 /// let x = std::f64::consts::FRAC_PI_4;
692 /// let abs_difference = (x.tan() - 1.0).abs();
693 ///
694 /// assert!(abs_difference < 1e-14);
695 /// ```
696 #[rustc_allow_incoherent_impl]
697 #[must_use = "method returns a new number and does not mutate the original value"]
698 #[stable(feature = "rust1", since = "1.0.0")]
699 #[inline]
700 pub fn tan(self) -> f64 {
701 unsafe { cmath::tan(self) }
702 }
703
704 /// Computes the arcsine of a number. Return value is in radians in
705 /// the range [-pi/2, pi/2] or NaN if the number is outside the range
706 /// [-1, 1].
707 ///
708 /// # Unspecified precision
709 ///
710 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
711 /// can even differ within the same execution from one invocation to the next.
712 /// This function currently corresponds to the `asin` from libc on Unix and
713 /// Windows. Note that this might change in the future.
714 ///
715 /// # Examples
716 ///
717 /// ```
718 /// let f = std::f64::consts::FRAC_PI_2;
719 ///
720 /// // asin(sin(pi/2))
721 /// let abs_difference = (f.sin().asin() - std::f64::consts::FRAC_PI_2).abs();
722 ///
723 /// assert!(abs_difference < 1e-10);
724 /// ```
725 #[doc(alias = "arcsin")]
726 #[rustc_allow_incoherent_impl]
727 #[must_use = "method returns a new number and does not mutate the original value"]
728 #[stable(feature = "rust1", since = "1.0.0")]
729 #[inline]
730 pub fn asin(self) -> f64 {
731 unsafe { cmath::asin(self) }
732 }
733
734 /// Computes the arccosine of a number. Return value is in radians in
735 /// the range [0, pi] or NaN if the number is outside the range
736 /// [-1, 1].
737 ///
738 /// # Unspecified precision
739 ///
740 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
741 /// can even differ within the same execution from one invocation to the next.
742 /// This function currently corresponds to the `acos` from libc on Unix and
743 /// Windows. Note that this might change in the future.
744 ///
745 /// # Examples
746 ///
747 /// ```
748 /// let f = std::f64::consts::FRAC_PI_4;
749 ///
750 /// // acos(cos(pi/4))
751 /// let abs_difference = (f.cos().acos() - std::f64::consts::FRAC_PI_4).abs();
752 ///
753 /// assert!(abs_difference < 1e-10);
754 /// ```
755 #[doc(alias = "arccos")]
756 #[rustc_allow_incoherent_impl]
757 #[must_use = "method returns a new number and does not mutate the original value"]
758 #[stable(feature = "rust1", since = "1.0.0")]
759 #[inline]
760 pub fn acos(self) -> f64 {
761 unsafe { cmath::acos(self) }
762 }
763
764 /// Computes the arctangent of a number. Return value is in radians in the
765 /// range [-pi/2, pi/2];
766 ///
767 /// # Unspecified precision
768 ///
769 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
770 /// can even differ within the same execution from one invocation to the next.
771 /// This function currently corresponds to the `atan` from libc on Unix and
772 /// Windows. Note that this might change in the future.
773 ///
774 /// # Examples
775 ///
776 /// ```
777 /// let f = 1.0_f64;
778 ///
779 /// // atan(tan(1))
780 /// let abs_difference = (f.tan().atan() - 1.0).abs();
781 ///
782 /// assert!(abs_difference < 1e-10);
783 /// ```
784 #[doc(alias = "arctan")]
785 #[rustc_allow_incoherent_impl]
786 #[must_use = "method returns a new number and does not mutate the original value"]
787 #[stable(feature = "rust1", since = "1.0.0")]
788 #[inline]
789 pub fn atan(self) -> f64 {
790 unsafe { cmath::atan(self) }
791 }
792
793 /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`) in radians.
794 ///
795 /// * `x = 0`, `y = 0`: `0`
796 /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]`
797 /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
798 /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
799 ///
800 /// # Unspecified precision
801 ///
802 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
803 /// can even differ within the same execution from one invocation to the next.
804 /// This function currently corresponds to the `atan2` from libc on Unix
805 /// and Windows. Note that this might change in the future.
806 ///
807 /// # Examples
808 ///
809 /// ```
810 /// // Positive angles measured counter-clockwise
811 /// // from positive x axis
812 /// // -pi/4 radians (45 deg clockwise)
813 /// let x1 = 3.0_f64;
814 /// let y1 = -3.0_f64;
815 ///
816 /// // 3pi/4 radians (135 deg counter-clockwise)
817 /// let x2 = -3.0_f64;
818 /// let y2 = 3.0_f64;
819 ///
820 /// let abs_difference_1 = (y1.atan2(x1) - (-std::f64::consts::FRAC_PI_4)).abs();
821 /// let abs_difference_2 = (y2.atan2(x2) - (3.0 * std::f64::consts::FRAC_PI_4)).abs();
822 ///
823 /// assert!(abs_difference_1 < 1e-10);
824 /// assert!(abs_difference_2 < 1e-10);
825 /// ```
826 #[rustc_allow_incoherent_impl]
827 #[must_use = "method returns a new number and does not mutate the original value"]
828 #[stable(feature = "rust1", since = "1.0.0")]
829 #[inline]
830 pub fn atan2(self, other: f64) -> f64 {
831 unsafe { cmath::atan2(self, other) }
832 }
833
834 /// Simultaneously computes the sine and cosine of the number, `x`. Returns
835 /// `(sin(x), cos(x))`.
836 ///
837 /// # Unspecified precision
838 ///
839 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
840 /// can even differ within the same execution from one invocation to the next.
841 /// This function currently corresponds to the `(f64::sin(x),
842 /// f64::cos(x))`. Note that this might change in the future.
843 ///
844 /// # Examples
845 ///
846 /// ```
847 /// let x = std::f64::consts::FRAC_PI_4;
848 /// let f = x.sin_cos();
849 ///
850 /// let abs_difference_0 = (f.0 - x.sin()).abs();
851 /// let abs_difference_1 = (f.1 - x.cos()).abs();
852 ///
853 /// assert!(abs_difference_0 < 1e-10);
854 /// assert!(abs_difference_1 < 1e-10);
855 /// ```
856 #[doc(alias = "sincos")]
857 #[rustc_allow_incoherent_impl]
858 #[stable(feature = "rust1", since = "1.0.0")]
859 #[inline]
860 pub fn sin_cos(self) -> (f64, f64) {
861 (self.sin(), self.cos())
862 }
863
864 /// Returns `e^(self) - 1` in a way that is accurate even if the
865 /// number is close to zero.
866 ///
867 /// # Unspecified precision
868 ///
869 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
870 /// can even differ within the same execution from one invocation to the next.
871 /// This function currently corresponds to the `expm1` from libc on Unix
872 /// and Windows. Note that this might change in the future.
873 ///
874 /// # Examples
875 ///
876 /// ```
877 /// let x = 1e-16_f64;
878 ///
879 /// // for very small x, e^x is approximately 1 + x + x^2 / 2
880 /// let approx = x + x * x / 2.0;
881 /// let abs_difference = (x.exp_m1() - approx).abs();
882 ///
883 /// assert!(abs_difference < 1e-20);
884 /// ```
885 #[rustc_allow_incoherent_impl]
886 #[must_use = "method returns a new number and does not mutate the original value"]
887 #[stable(feature = "rust1", since = "1.0.0")]
888 #[inline]
889 pub fn exp_m1(self) -> f64 {
890 unsafe { cmath::expm1(self) }
891 }
892
893 /// Returns `ln(1+n)` (natural logarithm) more accurately than if
894 /// the operations were performed separately.
895 ///
896 /// # Unspecified precision
897 ///
898 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
899 /// can even differ within the same execution from one invocation to the next.
900 /// This function currently corresponds to the `log1p` from libc on Unix
901 /// and Windows. Note that this might change in the future.
902 ///
903 /// # Examples
904 ///
905 /// ```
906 /// let x = 1e-16_f64;
907 ///
908 /// // for very small x, ln(1 + x) is approximately x - x^2 / 2
909 /// let approx = x - x * x / 2.0;
910 /// let abs_difference = (x.ln_1p() - approx).abs();
911 ///
912 /// assert!(abs_difference < 1e-20);
913 /// ```
914 #[doc(alias = "log1p")]
915 #[rustc_allow_incoherent_impl]
916 #[must_use = "method returns a new number and does not mutate the original value"]
917 #[stable(feature = "rust1", since = "1.0.0")]
918 #[inline]
919 pub fn ln_1p(self) -> f64 {
920 unsafe { cmath::log1p(self) }
921 }
922
923 /// Hyperbolic sine function.
924 ///
925 /// # Unspecified precision
926 ///
927 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
928 /// can even differ within the same execution from one invocation to the next.
929 /// This function currently corresponds to the `sinh` from libc on Unix
930 /// and Windows. Note that this might change in the future.
931 ///
932 /// # Examples
933 ///
934 /// ```
935 /// let e = std::f64::consts::E;
936 /// let x = 1.0_f64;
937 ///
938 /// let f = x.sinh();
939 /// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
940 /// let g = ((e * e) - 1.0) / (2.0 * e);
941 /// let abs_difference = (f - g).abs();
942 ///
943 /// assert!(abs_difference < 1e-10);
944 /// ```
945 #[rustc_allow_incoherent_impl]
946 #[must_use = "method returns a new number and does not mutate the original value"]
947 #[stable(feature = "rust1", since = "1.0.0")]
948 #[inline]
949 pub fn sinh(self) -> f64 {
950 unsafe { cmath::sinh(self) }
951 }
952
953 /// Hyperbolic cosine function.
954 ///
955 /// # Unspecified precision
956 ///
957 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
958 /// can even differ within the same execution from one invocation to the next.
959 /// This function currently corresponds to the `cosh` from libc on Unix
960 /// and Windows. Note that this might change in the future.
961 ///
962 /// # Examples
963 ///
964 /// ```
965 /// let e = std::f64::consts::E;
966 /// let x = 1.0_f64;
967 /// let f = x.cosh();
968 /// // Solving cosh() at 1 gives this result
969 /// let g = ((e * e) + 1.0) / (2.0 * e);
970 /// let abs_difference = (f - g).abs();
971 ///
972 /// // Same result
973 /// assert!(abs_difference < 1.0e-10);
974 /// ```
975 #[rustc_allow_incoherent_impl]
976 #[must_use = "method returns a new number and does not mutate the original value"]
977 #[stable(feature = "rust1", since = "1.0.0")]
978 #[inline]
979 pub fn cosh(self) -> f64 {
980 unsafe { cmath::cosh(self) }
981 }
982
983 /// Hyperbolic tangent function.
984 ///
985 /// # Unspecified precision
986 ///
987 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
988 /// can even differ within the same execution from one invocation to the next.
989 /// This function currently corresponds to the `tanh` from libc on Unix
990 /// and Windows. Note that this might change in the future.
991 ///
992 /// # Examples
993 ///
994 /// ```
995 /// let e = std::f64::consts::E;
996 /// let x = 1.0_f64;
997 ///
998 /// let f = x.tanh();
999 /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
1000 /// let g = (1.0 - e.powi(-2)) / (1.0 + e.powi(-2));
1001 /// let abs_difference = (f - g).abs();
1002 ///
1003 /// assert!(abs_difference < 1.0e-10);
1004 /// ```
1005 #[rustc_allow_incoherent_impl]
1006 #[must_use = "method returns a new number and does not mutate the original value"]
1007 #[stable(feature = "rust1", since = "1.0.0")]
1008 #[inline]
1009 pub fn tanh(self) -> f64 {
1010 unsafe { cmath::tanh(self) }
1011 }
1012
1013 /// Inverse hyperbolic sine function.
1014 ///
1015 /// # Unspecified precision
1016 ///
1017 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
1018 /// can even differ within the same execution from one invocation to the next.
1019 ///
1020 /// # Examples
1021 ///
1022 /// ```
1023 /// let x = 1.0_f64;
1024 /// let f = x.sinh().asinh();
1025 ///
1026 /// let abs_difference = (f - x).abs();
1027 ///
1028 /// assert!(abs_difference < 1.0e-10);
1029 /// ```
1030 #[doc(alias = "arcsinh")]
1031 #[rustc_allow_incoherent_impl]
1032 #[must_use = "method returns a new number and does not mutate the original value"]
1033 #[stable(feature = "rust1", since = "1.0.0")]
1034 #[inline]
1035 pub fn asinh(self) -> f64 {
1036 let ax = self.abs();
1037 let ix = 1.0 / ax;
1038 (ax + (ax / (Self::hypot(1.0, ix) + ix))).ln_1p().copysign(self)
1039 }
1040
1041 /// Inverse hyperbolic cosine function.
1042 ///
1043 /// # Unspecified precision
1044 ///
1045 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
1046 /// can even differ within the same execution from one invocation to the next.
1047 ///
1048 /// # Examples
1049 ///
1050 /// ```
1051 /// let x = 1.0_f64;
1052 /// let f = x.cosh().acosh();
1053 ///
1054 /// let abs_difference = (f - x).abs();
1055 ///
1056 /// assert!(abs_difference < 1.0e-10);
1057 /// ```
1058 #[doc(alias = "arccosh")]
1059 #[rustc_allow_incoherent_impl]
1060 #[must_use = "method returns a new number and does not mutate the original value"]
1061 #[stable(feature = "rust1", since = "1.0.0")]
1062 #[inline]
1063 pub fn acosh(self) -> f64 {
1064 if self < 1.0 {
1065 Self::NAN
1066 } else {
1067 (self + ((self - 1.0).sqrt() * (self + 1.0).sqrt())).ln()
1068 }
1069 }
1070
1071 /// Inverse hyperbolic tangent function.
1072 ///
1073 /// # Unspecified precision
1074 ///
1075 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
1076 /// can even differ within the same execution from one invocation to the next.
1077 ///
1078 /// # Examples
1079 ///
1080 /// ```
1081 /// let e = std::f64::consts::E;
1082 /// let f = e.tanh().atanh();
1083 ///
1084 /// let abs_difference = (f - e).abs();
1085 ///
1086 /// assert!(abs_difference < 1.0e-10);
1087 /// ```
1088 #[doc(alias = "arctanh")]
1089 #[rustc_allow_incoherent_impl]
1090 #[must_use = "method returns a new number and does not mutate the original value"]
1091 #[stable(feature = "rust1", since = "1.0.0")]
1092 #[inline]
1093 pub fn atanh(self) -> f64 {
1094 0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
1095 }
1096
1097 /// Gamma function.
1098 ///
1099 /// # Unspecified precision
1100 ///
1101 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
1102 /// can even differ within the same execution from one invocation to the next.
1103 /// This function currently corresponds to the `tgamma` from libc on Unix
1104 /// and Windows. Note that this might change in the future.
1105 ///
1106 /// # Examples
1107 ///
1108 /// ```
1109 /// #![feature(float_gamma)]
1110 /// let x = 5.0f64;
1111 ///
1112 /// let abs_difference = (x.gamma() - 24.0).abs();
1113 ///
1114 /// assert!(abs_difference <= f64::EPSILON);
1115 /// ```
1116 #[rustc_allow_incoherent_impl]
1117 #[must_use = "method returns a new number and does not mutate the original value"]
1118 #[unstable(feature = "float_gamma", issue = "99842")]
1119 #[inline]
1120 pub fn gamma(self) -> f64 {
1121 unsafe { cmath::tgamma(self) }
1122 }
1123
1124 /// Natural logarithm of the absolute value of the gamma function
1125 ///
1126 /// The integer part of the tuple indicates the sign of the gamma function.
1127 ///
1128 /// # Unspecified precision
1129 ///
1130 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
1131 /// can even differ within the same execution from one invocation to the next.
1132 /// This function currently corresponds to the `lgamma_r` from libc on Unix
1133 /// and Windows. Note that this might change in the future.
1134 ///
1135 /// # Examples
1136 ///
1137 /// ```
1138 /// #![feature(float_gamma)]
1139 /// let x = 2.0f64;
1140 ///
1141 /// let abs_difference = (x.ln_gamma().0 - 0.0).abs();
1142 ///
1143 /// assert!(abs_difference <= f64::EPSILON);
1144 /// ```
1145 #[rustc_allow_incoherent_impl]
1146 #[must_use = "method returns a new number and does not mutate the original value"]
1147 #[unstable(feature = "float_gamma", issue = "99842")]
1148 #[inline]
1149 pub fn ln_gamma(self) -> (f64, i32) {
1150 let mut signgamp: i32 = 0;
1151 let x = unsafe { cmath::lgamma_r(self, &mut signgamp) };
1152 (x, signgamp)
1153 }
1154
1155 /// Error function.
1156 ///
1157 /// # Unspecified precision
1158 ///
1159 /// The precision of this function is non-deterministic. This means it varies by platform,
1160 /// Rust version, and can even differ within the same execution from one invocation to the next.
1161 ///
1162 /// This function currently corresponds to the `erf` from libc on Unix
1163 /// and Windows. Note that this might change in the future.
1164 ///
1165 /// # Examples
1166 ///
1167 /// ```
1168 /// #![feature(float_erf)]
1169 /// /// The error function relates what percent of a normal distribution lies
1170 /// /// within `x` standard deviations (scaled by `1/sqrt(2)`).
1171 /// fn within_standard_deviations(x: f64) -> f64 {
1172 /// (x * std::f64::consts::FRAC_1_SQRT_2).erf() * 100.0
1173 /// }
1174 ///
1175 /// // 68% of a normal distribution is within one standard deviation
1176 /// assert!((within_standard_deviations(1.0) - 68.269).abs() < 0.01);
1177 /// // 95% of a normal distribution is within two standard deviations
1178 /// assert!((within_standard_deviations(2.0) - 95.450).abs() < 0.01);
1179 /// // 99.7% of a normal distribution is within three standard deviations
1180 /// assert!((within_standard_deviations(3.0) - 99.730).abs() < 0.01);
1181 /// ```
1182 #[rustc_allow_incoherent_impl]
1183 #[must_use = "method returns a new number and does not mutate the original value"]
1184 #[unstable(feature = "float_erf", issue = "136321")]
1185 #[inline]
1186 pub fn erf(self) -> f64 {
1187 unsafe { cmath::erf(self) }
1188 }
1189
1190 /// Complementary error function.
1191 ///
1192 /// # Unspecified precision
1193 ///
1194 /// The precision of this function is non-deterministic. This means it varies by platform,
1195 /// Rust version, and can even differ within the same execution from one invocation to the next.
1196 ///
1197 /// This function currently corresponds to the `erfc` from libc on Unix
1198 /// and Windows. Note that this might change in the future.
1199 ///
1200 /// # Examples
1201 ///
1202 /// ```
1203 /// #![feature(float_erf)]
1204 /// let x: f64 = 0.123;
1205 ///
1206 /// let one = x.erf() + x.erfc();
1207 /// let abs_difference = (one - 1.0).abs();
1208 ///
1209 /// assert!(abs_difference <= f64::EPSILON);
1210 /// ```
1211 #[rustc_allow_incoherent_impl]
1212 #[must_use = "method returns a new number and does not mutate the original value"]
1213 #[unstable(feature = "float_erf", issue = "136321")]
1214 #[inline]
1215 pub fn erfc(self) -> f64 {
1216 unsafe { cmath::erfc(self) }
1217 }
1218}