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 core::f64::math::floor(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 core::f64::math::ceil(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 core::f64::math::round(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 core::f64::math::round_ties_even(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 core::f64::math::trunc(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 core::f64::math::fract(self)
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 core::f64::math::mul_add(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 core::f64::math::div_euclid(self, rhs)
246 }
247
248 /// Calculates the least nonnegative remainder of `self (mod rhs)`.
249 ///
250 /// In particular, the return value `r` satisfies `0.0 <= r < rhs.abs()` in
251 /// most cases. However, due to a floating point round-off error it can
252 /// result in `r == rhs.abs()`, violating the mathematical definition, if
253 /// `self` is much smaller than `rhs.abs()` in magnitude and `self < 0.0`.
254 /// This result is not an element of the function's codomain, but it is the
255 /// closest floating point number in the real numbers and thus fulfills the
256 /// property `self == self.div_euclid(rhs) * rhs + self.rem_euclid(rhs)`
257 /// approximately.
258 ///
259 /// # Precision
260 ///
261 /// The result of this operation is guaranteed to be the rounded
262 /// infinite-precision result.
263 ///
264 /// # Examples
265 ///
266 /// ```
267 /// let a: f64 = 7.0;
268 /// let b = 4.0;
269 /// assert_eq!(a.rem_euclid(b), 3.0);
270 /// assert_eq!((-a).rem_euclid(b), 1.0);
271 /// assert_eq!(a.rem_euclid(-b), 3.0);
272 /// assert_eq!((-a).rem_euclid(-b), 1.0);
273 /// // limitation due to round-off error
274 /// assert!((-f64::EPSILON).rem_euclid(3.0) != 0.0);
275 /// ```
276 #[doc(alias = "modulo", alias = "mod")]
277 #[rustc_allow_incoherent_impl]
278 #[must_use = "method returns a new number and does not mutate the original value"]
279 #[inline]
280 #[stable(feature = "euclidean_division", since = "1.38.0")]
281 pub fn rem_euclid(self, rhs: f64) -> f64 {
282 core::f64::math::rem_euclid(self, rhs)
283 }
284
285 /// Raises a number to an integer power.
286 ///
287 /// Using this function is generally faster than using `powf`.
288 /// It might have a different sequence of rounding operations than `powf`,
289 /// so the results are not guaranteed to agree.
290 ///
291 /// # Unspecified precision
292 ///
293 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
294 /// can even differ within the same execution from one invocation to the next.
295 ///
296 /// # Examples
297 ///
298 /// ```
299 /// let x = 2.0_f64;
300 /// let abs_difference = (x.powi(2) - (x * x)).abs();
301 /// assert!(abs_difference <= f64::EPSILON);
302 ///
303 /// assert_eq!(f64::powi(f64::NAN, 0), 1.0);
304 /// ```
305 #[rustc_allow_incoherent_impl]
306 #[must_use = "method returns a new number and does not mutate the original value"]
307 #[stable(feature = "rust1", since = "1.0.0")]
308 #[inline]
309 pub fn powi(self, n: i32) -> f64 {
310 core::f64::math::powi(self, n)
311 }
312
313 /// Raises a number to a floating point power.
314 ///
315 /// # Unspecified precision
316 ///
317 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
318 /// can even differ within the same execution from one invocation to the next.
319 ///
320 /// # Examples
321 ///
322 /// ```
323 /// let x = 2.0_f64;
324 /// let abs_difference = (x.powf(2.0) - (x * x)).abs();
325 /// assert!(abs_difference <= f64::EPSILON);
326 ///
327 /// assert_eq!(f64::powf(1.0, f64::NAN), 1.0);
328 /// assert_eq!(f64::powf(f64::NAN, 0.0), 1.0);
329 /// ```
330 #[rustc_allow_incoherent_impl]
331 #[must_use = "method returns a new number and does not mutate the original value"]
332 #[stable(feature = "rust1", since = "1.0.0")]
333 #[inline]
334 pub fn powf(self, n: f64) -> f64 {
335 unsafe { intrinsics::powf64(self, n) }
336 }
337
338 /// Returns the square root of a number.
339 ///
340 /// Returns NaN if `self` is a negative number other than `-0.0`.
341 ///
342 /// # Precision
343 ///
344 /// The result of this operation is guaranteed to be the rounded
345 /// infinite-precision result. It is specified by IEEE 754 as `squareRoot`
346 /// and guaranteed not to change.
347 ///
348 /// # Examples
349 ///
350 /// ```
351 /// let positive = 4.0_f64;
352 /// let negative = -4.0_f64;
353 /// let negative_zero = -0.0_f64;
354 ///
355 /// assert_eq!(positive.sqrt(), 2.0);
356 /// assert!(negative.sqrt().is_nan());
357 /// assert!(negative_zero.sqrt() == negative_zero);
358 /// ```
359 #[doc(alias = "squareRoot")]
360 #[rustc_allow_incoherent_impl]
361 #[must_use = "method returns a new number and does not mutate the original value"]
362 #[stable(feature = "rust1", since = "1.0.0")]
363 #[inline]
364 pub fn sqrt(self) -> f64 {
365 core::f64::math::sqrt(self)
366 }
367
368 /// Returns `e^(self)`, (the exponential function).
369 ///
370 /// # Unspecified precision
371 ///
372 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
373 /// can even differ within the same execution from one invocation to the next.
374 ///
375 /// # Examples
376 ///
377 /// ```
378 /// let one = 1.0_f64;
379 /// // e^1
380 /// let e = one.exp();
381 ///
382 /// // ln(e) - 1 == 0
383 /// let abs_difference = (e.ln() - 1.0).abs();
384 ///
385 /// assert!(abs_difference < 1e-10);
386 /// ```
387 #[rustc_allow_incoherent_impl]
388 #[must_use = "method returns a new number and does not mutate the original value"]
389 #[stable(feature = "rust1", since = "1.0.0")]
390 #[inline]
391 pub fn exp(self) -> f64 {
392 unsafe { intrinsics::expf64(self) }
393 }
394
395 /// Returns `2^(self)`.
396 ///
397 /// # Unspecified precision
398 ///
399 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
400 /// can even differ within the same execution from one invocation to the next.
401 ///
402 /// # Examples
403 ///
404 /// ```
405 /// let f = 2.0_f64;
406 ///
407 /// // 2^2 - 4 == 0
408 /// let abs_difference = (f.exp2() - 4.0).abs();
409 ///
410 /// assert!(abs_difference < 1e-10);
411 /// ```
412 #[rustc_allow_incoherent_impl]
413 #[must_use = "method returns a new number and does not mutate the original value"]
414 #[stable(feature = "rust1", since = "1.0.0")]
415 #[inline]
416 pub fn exp2(self) -> f64 {
417 unsafe { intrinsics::exp2f64(self) }
418 }
419
420 /// Returns the natural logarithm of the number.
421 ///
422 /// This returns NaN when the number is negative, and negative infinity when number is zero.
423 ///
424 /// # Unspecified precision
425 ///
426 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
427 /// can even differ within the same execution from one invocation to the next.
428 ///
429 /// # Examples
430 ///
431 /// ```
432 /// let one = 1.0_f64;
433 /// // e^1
434 /// let e = one.exp();
435 ///
436 /// // ln(e) - 1 == 0
437 /// let abs_difference = (e.ln() - 1.0).abs();
438 ///
439 /// assert!(abs_difference < 1e-10);
440 /// ```
441 ///
442 /// Non-positive values:
443 /// ```
444 /// assert_eq!(0_f64.ln(), f64::NEG_INFINITY);
445 /// assert!((-42_f64).ln().is_nan());
446 /// ```
447 #[rustc_allow_incoherent_impl]
448 #[must_use = "method returns a new number and does not mutate the original value"]
449 #[stable(feature = "rust1", since = "1.0.0")]
450 #[inline]
451 pub fn ln(self) -> f64 {
452 unsafe { intrinsics::logf64(self) }
453 }
454
455 /// Returns the logarithm of the number with respect to an arbitrary base.
456 ///
457 /// This returns NaN when the number is negative, and negative infinity when number is zero.
458 ///
459 /// The result might not be correctly rounded owing to implementation details;
460 /// `self.log2()` can produce more accurate results for base 2, and
461 /// `self.log10()` can produce more accurate results for base 10.
462 ///
463 /// # Unspecified precision
464 ///
465 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
466 /// can even differ within the same execution from one invocation to the next.
467 ///
468 /// # Examples
469 ///
470 /// ```
471 /// let twenty_five = 25.0_f64;
472 ///
473 /// // log5(25) - 2 == 0
474 /// let abs_difference = (twenty_five.log(5.0) - 2.0).abs();
475 ///
476 /// assert!(abs_difference < 1e-10);
477 /// ```
478 ///
479 /// Non-positive values:
480 /// ```
481 /// assert_eq!(0_f64.log(10.0), f64::NEG_INFINITY);
482 /// assert!((-42_f64).log(10.0).is_nan());
483 /// ```
484 #[rustc_allow_incoherent_impl]
485 #[must_use = "method returns a new number and does not mutate the original value"]
486 #[stable(feature = "rust1", since = "1.0.0")]
487 #[inline]
488 pub fn log(self, base: f64) -> f64 {
489 self.ln() / base.ln()
490 }
491
492 /// Returns the base 2 logarithm of the number.
493 ///
494 /// This returns NaN when the number is negative, and negative infinity when number is zero.
495 ///
496 /// # Unspecified precision
497 ///
498 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
499 /// can even differ within the same execution from one invocation to the next.
500 ///
501 /// # Examples
502 ///
503 /// ```
504 /// let four = 4.0_f64;
505 ///
506 /// // log2(4) - 2 == 0
507 /// let abs_difference = (four.log2() - 2.0).abs();
508 ///
509 /// assert!(abs_difference < 1e-10);
510 /// ```
511 ///
512 /// Non-positive values:
513 /// ```
514 /// assert_eq!(0_f64.log2(), f64::NEG_INFINITY);
515 /// assert!((-42_f64).log2().is_nan());
516 /// ```
517 #[rustc_allow_incoherent_impl]
518 #[must_use = "method returns a new number and does not mutate the original value"]
519 #[stable(feature = "rust1", since = "1.0.0")]
520 #[inline]
521 pub fn log2(self) -> f64 {
522 unsafe { intrinsics::log2f64(self) }
523 }
524
525 /// Returns the base 10 logarithm of the number.
526 ///
527 /// This returns NaN when the number is negative, and negative infinity when number is zero.
528 ///
529 /// # Unspecified precision
530 ///
531 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
532 /// can even differ within the same execution from one invocation to the next.
533 ///
534 /// # Examples
535 ///
536 /// ```
537 /// let hundred = 100.0_f64;
538 ///
539 /// // log10(100) - 2 == 0
540 /// let abs_difference = (hundred.log10() - 2.0).abs();
541 ///
542 /// assert!(abs_difference < 1e-10);
543 /// ```
544 ///
545 /// Non-positive values:
546 /// ```
547 /// assert_eq!(0_f64.log10(), f64::NEG_INFINITY);
548 /// assert!((-42_f64).log10().is_nan());
549 /// ```
550 #[rustc_allow_incoherent_impl]
551 #[must_use = "method returns a new number and does not mutate the original value"]
552 #[stable(feature = "rust1", since = "1.0.0")]
553 #[inline]
554 pub fn log10(self) -> f64 {
555 unsafe { intrinsics::log10f64(self) }
556 }
557
558 /// The positive difference of two numbers.
559 ///
560 /// * If `self <= other`: `0.0`
561 /// * Else: `self - other`
562 ///
563 /// # Unspecified precision
564 ///
565 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
566 /// can even differ within the same execution from one invocation to the next.
567 /// This function currently corresponds to the `fdim` from libc on Unix and
568 /// Windows. Note that this might change in the future.
569 ///
570 /// # Examples
571 ///
572 /// ```
573 /// let x = 3.0_f64;
574 /// let y = -3.0_f64;
575 ///
576 /// let abs_difference_x = (x.abs_sub(1.0) - 2.0).abs();
577 /// let abs_difference_y = (y.abs_sub(1.0) - 0.0).abs();
578 ///
579 /// assert!(abs_difference_x < 1e-10);
580 /// assert!(abs_difference_y < 1e-10);
581 /// ```
582 #[rustc_allow_incoherent_impl]
583 #[must_use = "method returns a new number and does not mutate the original value"]
584 #[stable(feature = "rust1", since = "1.0.0")]
585 #[inline]
586 #[deprecated(
587 since = "1.10.0",
588 note = "you probably meant `(self - other).abs()`: \
589 this operation is `(self - other).max(0.0)` \
590 except that `abs_sub` also propagates NaNs (also \
591 known as `fdim` in C). If you truly need the positive \
592 difference, consider using that expression or the C function \
593 `fdim`, depending on how you wish to handle NaN (please consider \
594 filing an issue describing your use-case too)."
595 )]
596 pub fn abs_sub(self, other: f64) -> f64 {
597 #[allow(deprecated)]
598 core::f64::math::abs_sub(self, other)
599 }
600
601 /// Returns the cube root of a number.
602 ///
603 /// # Unspecified precision
604 ///
605 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
606 /// can even differ within the same execution from one invocation to the next.
607 /// This function currently corresponds to the `cbrt` from libc on Unix and
608 /// Windows. Note that this might change in the future.
609 ///
610 /// # Examples
611 ///
612 /// ```
613 /// let x = 8.0_f64;
614 ///
615 /// // x^(1/3) - 2 == 0
616 /// let abs_difference = (x.cbrt() - 2.0).abs();
617 ///
618 /// assert!(abs_difference < 1e-10);
619 /// ```
620 #[rustc_allow_incoherent_impl]
621 #[must_use = "method returns a new number and does not mutate the original value"]
622 #[stable(feature = "rust1", since = "1.0.0")]
623 #[inline]
624 pub fn cbrt(self) -> f64 {
625 core::f64::math::cbrt(self)
626 }
627
628 /// Compute the distance between the origin and a point (`x`, `y`) on the
629 /// Euclidean plane. Equivalently, compute the length of the hypotenuse of a
630 /// right-angle triangle with other sides having length `x.abs()` and
631 /// `y.abs()`.
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 /// This function currently corresponds to the `hypot` from libc on Unix
638 /// and Windows. Note that this might change in the future.
639 ///
640 /// # Examples
641 ///
642 /// ```
643 /// let x = 2.0_f64;
644 /// let y = 3.0_f64;
645 ///
646 /// // sqrt(x^2 + y^2)
647 /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs();
648 ///
649 /// assert!(abs_difference < 1e-10);
650 /// ```
651 #[rustc_allow_incoherent_impl]
652 #[must_use = "method returns a new number and does not mutate the original value"]
653 #[stable(feature = "rust1", since = "1.0.0")]
654 #[inline]
655 pub fn hypot(self, other: f64) -> f64 {
656 cmath::hypot(self, other)
657 }
658
659 /// Computes the sine of a number (in radians).
660 ///
661 /// # Unspecified precision
662 ///
663 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
664 /// can even differ within the same execution from one invocation to the next.
665 ///
666 /// # Examples
667 ///
668 /// ```
669 /// let x = std::f64::consts::FRAC_PI_2;
670 ///
671 /// let abs_difference = (x.sin() - 1.0).abs();
672 ///
673 /// assert!(abs_difference < 1e-10);
674 /// ```
675 #[rustc_allow_incoherent_impl]
676 #[must_use = "method returns a new number and does not mutate the original value"]
677 #[stable(feature = "rust1", since = "1.0.0")]
678 #[inline]
679 pub fn sin(self) -> f64 {
680 unsafe { intrinsics::sinf64(self) }
681 }
682
683 /// Computes the cosine of a number (in radians).
684 ///
685 /// # Unspecified precision
686 ///
687 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
688 /// can even differ within the same execution from one invocation to the next.
689 ///
690 /// # Examples
691 ///
692 /// ```
693 /// let x = 2.0 * std::f64::consts::PI;
694 ///
695 /// let abs_difference = (x.cos() - 1.0).abs();
696 ///
697 /// assert!(abs_difference < 1e-10);
698 /// ```
699 #[rustc_allow_incoherent_impl]
700 #[must_use = "method returns a new number and does not mutate the original value"]
701 #[stable(feature = "rust1", since = "1.0.0")]
702 #[inline]
703 pub fn cos(self) -> f64 {
704 unsafe { intrinsics::cosf64(self) }
705 }
706
707 /// Computes the tangent of a number (in radians).
708 ///
709 /// # Unspecified precision
710 ///
711 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
712 /// can even differ within the same execution from one invocation to the next.
713 /// This function currently corresponds to the `tan` from libc on Unix and
714 /// Windows. Note that this might change in the future.
715 ///
716 /// # Examples
717 ///
718 /// ```
719 /// let x = std::f64::consts::FRAC_PI_4;
720 /// let abs_difference = (x.tan() - 1.0).abs();
721 ///
722 /// assert!(abs_difference < 1e-14);
723 /// ```
724 #[rustc_allow_incoherent_impl]
725 #[must_use = "method returns a new number and does not mutate the original value"]
726 #[stable(feature = "rust1", since = "1.0.0")]
727 #[inline]
728 pub fn tan(self) -> f64 {
729 cmath::tan(self)
730 }
731
732 /// Computes the arcsine of a number. Return value is in radians in
733 /// the range [-pi/2, pi/2] or NaN if the number is outside the range
734 /// [-1, 1].
735 ///
736 /// # Unspecified precision
737 ///
738 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
739 /// can even differ within the same execution from one invocation to the next.
740 /// This function currently corresponds to the `asin` from libc on Unix and
741 /// Windows. Note that this might change in the future.
742 ///
743 /// # Examples
744 ///
745 /// ```
746 /// let f = std::f64::consts::FRAC_PI_2;
747 ///
748 /// // asin(sin(pi/2))
749 /// let abs_difference = (f.sin().asin() - std::f64::consts::FRAC_PI_2).abs();
750 ///
751 /// assert!(abs_difference < 1e-10);
752 /// ```
753 #[doc(alias = "arcsin")]
754 #[rustc_allow_incoherent_impl]
755 #[must_use = "method returns a new number and does not mutate the original value"]
756 #[stable(feature = "rust1", since = "1.0.0")]
757 #[inline]
758 pub fn asin(self) -> f64 {
759 cmath::asin(self)
760 }
761
762 /// Computes the arccosine of a number. Return value is in radians in
763 /// the range [0, pi] or NaN if the number is outside the range
764 /// [-1, 1].
765 ///
766 /// # Unspecified precision
767 ///
768 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
769 /// can even differ within the same execution from one invocation to the next.
770 /// This function currently corresponds to the `acos` from libc on Unix and
771 /// Windows. Note that this might change in the future.
772 ///
773 /// # Examples
774 ///
775 /// ```
776 /// let f = std::f64::consts::FRAC_PI_4;
777 ///
778 /// // acos(cos(pi/4))
779 /// let abs_difference = (f.cos().acos() - std::f64::consts::FRAC_PI_4).abs();
780 ///
781 /// assert!(abs_difference < 1e-10);
782 /// ```
783 #[doc(alias = "arccos")]
784 #[rustc_allow_incoherent_impl]
785 #[must_use = "method returns a new number and does not mutate the original value"]
786 #[stable(feature = "rust1", since = "1.0.0")]
787 #[inline]
788 pub fn acos(self) -> f64 {
789 cmath::acos(self)
790 }
791
792 /// Computes the arctangent of a number. Return value is in radians in the
793 /// range [-pi/2, pi/2];
794 ///
795 /// # Unspecified precision
796 ///
797 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
798 /// can even differ within the same execution from one invocation to the next.
799 /// This function currently corresponds to the `atan` from libc on Unix and
800 /// Windows. Note that this might change in the future.
801 ///
802 /// # Examples
803 ///
804 /// ```
805 /// let f = 1.0_f64;
806 ///
807 /// // atan(tan(1))
808 /// let abs_difference = (f.tan().atan() - 1.0).abs();
809 ///
810 /// assert!(abs_difference < 1e-10);
811 /// ```
812 #[doc(alias = "arctan")]
813 #[rustc_allow_incoherent_impl]
814 #[must_use = "method returns a new number and does not mutate the original value"]
815 #[stable(feature = "rust1", since = "1.0.0")]
816 #[inline]
817 pub fn atan(self) -> f64 {
818 cmath::atan(self)
819 }
820
821 /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`) in radians.
822 ///
823 /// * `x = 0`, `y = 0`: `0`
824 /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]`
825 /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
826 /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
827 ///
828 /// # Unspecified precision
829 ///
830 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
831 /// can even differ within the same execution from one invocation to the next.
832 /// This function currently corresponds to the `atan2` from libc on Unix
833 /// and Windows. Note that this might change in the future.
834 ///
835 /// # Examples
836 ///
837 /// ```
838 /// // Positive angles measured counter-clockwise
839 /// // from positive x axis
840 /// // -pi/4 radians (45 deg clockwise)
841 /// let x1 = 3.0_f64;
842 /// let y1 = -3.0_f64;
843 ///
844 /// // 3pi/4 radians (135 deg counter-clockwise)
845 /// let x2 = -3.0_f64;
846 /// let y2 = 3.0_f64;
847 ///
848 /// let abs_difference_1 = (y1.atan2(x1) - (-std::f64::consts::FRAC_PI_4)).abs();
849 /// let abs_difference_2 = (y2.atan2(x2) - (3.0 * std::f64::consts::FRAC_PI_4)).abs();
850 ///
851 /// assert!(abs_difference_1 < 1e-10);
852 /// assert!(abs_difference_2 < 1e-10);
853 /// ```
854 #[rustc_allow_incoherent_impl]
855 #[must_use = "method returns a new number and does not mutate the original value"]
856 #[stable(feature = "rust1", since = "1.0.0")]
857 #[inline]
858 pub fn atan2(self, other: f64) -> f64 {
859 cmath::atan2(self, other)
860 }
861
862 /// Simultaneously computes the sine and cosine of the number, `x`. Returns
863 /// `(sin(x), cos(x))`.
864 ///
865 /// # Unspecified precision
866 ///
867 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
868 /// can even differ within the same execution from one invocation to the next.
869 /// This function currently corresponds to the `(f64::sin(x),
870 /// f64::cos(x))`. Note that this might change in the future.
871 ///
872 /// # Examples
873 ///
874 /// ```
875 /// let x = std::f64::consts::FRAC_PI_4;
876 /// let f = x.sin_cos();
877 ///
878 /// let abs_difference_0 = (f.0 - x.sin()).abs();
879 /// let abs_difference_1 = (f.1 - x.cos()).abs();
880 ///
881 /// assert!(abs_difference_0 < 1e-10);
882 /// assert!(abs_difference_1 < 1e-10);
883 /// ```
884 #[doc(alias = "sincos")]
885 #[rustc_allow_incoherent_impl]
886 #[stable(feature = "rust1", since = "1.0.0")]
887 #[inline]
888 pub fn sin_cos(self) -> (f64, f64) {
889 (self.sin(), self.cos())
890 }
891
892 /// Returns `e^(self) - 1` in a way that is accurate even if the
893 /// number is close to zero.
894 ///
895 /// # Unspecified precision
896 ///
897 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
898 /// can even differ within the same execution from one invocation to the next.
899 /// This function currently corresponds to the `expm1` from libc on Unix
900 /// and Windows. Note that this might change in the future.
901 ///
902 /// # Examples
903 ///
904 /// ```
905 /// let x = 1e-16_f64;
906 ///
907 /// // for very small x, e^x is approximately 1 + x + x^2 / 2
908 /// let approx = x + x * x / 2.0;
909 /// let abs_difference = (x.exp_m1() - approx).abs();
910 ///
911 /// assert!(abs_difference < 1e-20);
912 /// ```
913 #[rustc_allow_incoherent_impl]
914 #[must_use = "method returns a new number and does not mutate the original value"]
915 #[stable(feature = "rust1", since = "1.0.0")]
916 #[inline]
917 pub fn exp_m1(self) -> f64 {
918 cmath::expm1(self)
919 }
920
921 /// Returns `ln(1+n)` (natural logarithm) more accurately than if
922 /// the operations were performed separately.
923 ///
924 /// This returns NaN when `n < -1.0`, and negative infinity when `n == -1.0`.
925 ///
926 /// # Unspecified precision
927 ///
928 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
929 /// can even differ within the same execution from one invocation to the next.
930 /// This function currently corresponds to the `log1p` from libc on Unix
931 /// and Windows. Note that this might change in the future.
932 ///
933 /// # Examples
934 ///
935 /// ```
936 /// let x = 1e-16_f64;
937 ///
938 /// // for very small x, ln(1 + x) is approximately x - x^2 / 2
939 /// let approx = x - x * x / 2.0;
940 /// let abs_difference = (x.ln_1p() - approx).abs();
941 ///
942 /// assert!(abs_difference < 1e-20);
943 /// ```
944 ///
945 /// Out-of-range values:
946 /// ```
947 /// assert_eq!((-1.0_f64).ln_1p(), f64::NEG_INFINITY);
948 /// assert!((-2.0_f64).ln_1p().is_nan());
949 /// ```
950 #[doc(alias = "log1p")]
951 #[rustc_allow_incoherent_impl]
952 #[must_use = "method returns a new number and does not mutate the original value"]
953 #[stable(feature = "rust1", since = "1.0.0")]
954 #[inline]
955 pub fn ln_1p(self) -> f64 {
956 cmath::log1p(self)
957 }
958
959 /// Hyperbolic sine function.
960 ///
961 /// # Unspecified precision
962 ///
963 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
964 /// can even differ within the same execution from one invocation to the next.
965 /// This function currently corresponds to the `sinh` from libc on Unix
966 /// and Windows. Note that this might change in the future.
967 ///
968 /// # Examples
969 ///
970 /// ```
971 /// let e = std::f64::consts::E;
972 /// let x = 1.0_f64;
973 ///
974 /// let f = x.sinh();
975 /// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
976 /// let g = ((e * e) - 1.0) / (2.0 * e);
977 /// let abs_difference = (f - g).abs();
978 ///
979 /// assert!(abs_difference < 1e-10);
980 /// ```
981 #[rustc_allow_incoherent_impl]
982 #[must_use = "method returns a new number and does not mutate the original value"]
983 #[stable(feature = "rust1", since = "1.0.0")]
984 #[inline]
985 pub fn sinh(self) -> f64 {
986 cmath::sinh(self)
987 }
988
989 /// Hyperbolic cosine function.
990 ///
991 /// # Unspecified precision
992 ///
993 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
994 /// can even differ within the same execution from one invocation to the next.
995 /// This function currently corresponds to the `cosh` from libc on Unix
996 /// and Windows. Note that this might change in the future.
997 ///
998 /// # Examples
999 ///
1000 /// ```
1001 /// let e = std::f64::consts::E;
1002 /// let x = 1.0_f64;
1003 /// let f = x.cosh();
1004 /// // Solving cosh() at 1 gives this result
1005 /// let g = ((e * e) + 1.0) / (2.0 * e);
1006 /// let abs_difference = (f - g).abs();
1007 ///
1008 /// // Same result
1009 /// assert!(abs_difference < 1.0e-10);
1010 /// ```
1011 #[rustc_allow_incoherent_impl]
1012 #[must_use = "method returns a new number and does not mutate the original value"]
1013 #[stable(feature = "rust1", since = "1.0.0")]
1014 #[inline]
1015 pub fn cosh(self) -> f64 {
1016 cmath::cosh(self)
1017 }
1018
1019 /// Hyperbolic tangent function.
1020 ///
1021 /// # Unspecified precision
1022 ///
1023 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
1024 /// can even differ within the same execution from one invocation to the next.
1025 /// This function currently corresponds to the `tanh` from libc on Unix
1026 /// and Windows. Note that this might change in the future.
1027 ///
1028 /// # Examples
1029 ///
1030 /// ```
1031 /// let e = std::f64::consts::E;
1032 /// let x = 1.0_f64;
1033 ///
1034 /// let f = x.tanh();
1035 /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
1036 /// let g = (1.0 - e.powi(-2)) / (1.0 + e.powi(-2));
1037 /// let abs_difference = (f - g).abs();
1038 ///
1039 /// assert!(abs_difference < 1.0e-10);
1040 /// ```
1041 #[rustc_allow_incoherent_impl]
1042 #[must_use = "method returns a new number and does not mutate the original value"]
1043 #[stable(feature = "rust1", since = "1.0.0")]
1044 #[inline]
1045 pub fn tanh(self) -> f64 {
1046 cmath::tanh(self)
1047 }
1048
1049 /// Inverse hyperbolic sine function.
1050 ///
1051 /// # Unspecified precision
1052 ///
1053 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
1054 /// can even differ within the same execution from one invocation to the next.
1055 ///
1056 /// # Examples
1057 ///
1058 /// ```
1059 /// let x = 1.0_f64;
1060 /// let f = x.sinh().asinh();
1061 ///
1062 /// let abs_difference = (f - x).abs();
1063 ///
1064 /// assert!(abs_difference < 1.0e-10);
1065 /// ```
1066 #[doc(alias = "arcsinh")]
1067 #[rustc_allow_incoherent_impl]
1068 #[must_use = "method returns a new number and does not mutate the original value"]
1069 #[stable(feature = "rust1", since = "1.0.0")]
1070 #[inline]
1071 pub fn asinh(self) -> f64 {
1072 let ax = self.abs();
1073 let ix = 1.0 / ax;
1074 (ax + (ax / (Self::hypot(1.0, ix) + ix))).ln_1p().copysign(self)
1075 }
1076
1077 /// Inverse hyperbolic cosine function.
1078 ///
1079 /// # Unspecified precision
1080 ///
1081 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
1082 /// can even differ within the same execution from one invocation to the next.
1083 ///
1084 /// # Examples
1085 ///
1086 /// ```
1087 /// let x = 1.0_f64;
1088 /// let f = x.cosh().acosh();
1089 ///
1090 /// let abs_difference = (f - x).abs();
1091 ///
1092 /// assert!(abs_difference < 1.0e-10);
1093 /// ```
1094 #[doc(alias = "arccosh")]
1095 #[rustc_allow_incoherent_impl]
1096 #[must_use = "method returns a new number and does not mutate the original value"]
1097 #[stable(feature = "rust1", since = "1.0.0")]
1098 #[inline]
1099 pub fn acosh(self) -> f64 {
1100 if self < 1.0 {
1101 Self::NAN
1102 } else {
1103 (self + ((self - 1.0).sqrt() * (self + 1.0).sqrt())).ln()
1104 }
1105 }
1106
1107 /// Inverse hyperbolic tangent function.
1108 ///
1109 /// # Unspecified precision
1110 ///
1111 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
1112 /// can even differ within the same execution from one invocation to the next.
1113 ///
1114 /// # Examples
1115 ///
1116 /// ```
1117 /// let e = std::f64::consts::E;
1118 /// let f = e.tanh().atanh();
1119 ///
1120 /// let abs_difference = (f - e).abs();
1121 ///
1122 /// assert!(abs_difference < 1.0e-10);
1123 /// ```
1124 #[doc(alias = "arctanh")]
1125 #[rustc_allow_incoherent_impl]
1126 #[must_use = "method returns a new number and does not mutate the original value"]
1127 #[stable(feature = "rust1", since = "1.0.0")]
1128 #[inline]
1129 pub fn atanh(self) -> f64 {
1130 0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
1131 }
1132
1133 /// Gamma function.
1134 ///
1135 /// # Unspecified precision
1136 ///
1137 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
1138 /// can even differ within the same execution from one invocation to the next.
1139 /// This function currently corresponds to the `tgamma` from libc on Unix
1140 /// and Windows. Note that this might change in the future.
1141 ///
1142 /// # Examples
1143 ///
1144 /// ```
1145 /// #![feature(float_gamma)]
1146 /// let x = 5.0f64;
1147 ///
1148 /// let abs_difference = (x.gamma() - 24.0).abs();
1149 ///
1150 /// assert!(abs_difference <= f64::EPSILON);
1151 /// ```
1152 #[rustc_allow_incoherent_impl]
1153 #[must_use = "method returns a new number and does not mutate the original value"]
1154 #[unstable(feature = "float_gamma", issue = "99842")]
1155 #[inline]
1156 pub fn gamma(self) -> f64 {
1157 cmath::tgamma(self)
1158 }
1159
1160 /// Natural logarithm of the absolute value of the gamma function
1161 ///
1162 /// The integer part of the tuple indicates the sign of the gamma function.
1163 ///
1164 /// # Unspecified precision
1165 ///
1166 /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
1167 /// can even differ within the same execution from one invocation to the next.
1168 /// This function currently corresponds to the `lgamma_r` from libc on Unix
1169 /// and Windows. Note that this might change in the future.
1170 ///
1171 /// # Examples
1172 ///
1173 /// ```
1174 /// #![feature(float_gamma)]
1175 /// let x = 2.0f64;
1176 ///
1177 /// let abs_difference = (x.ln_gamma().0 - 0.0).abs();
1178 ///
1179 /// assert!(abs_difference <= f64::EPSILON);
1180 /// ```
1181 #[rustc_allow_incoherent_impl]
1182 #[must_use = "method returns a new number and does not mutate the original value"]
1183 #[unstable(feature = "float_gamma", issue = "99842")]
1184 #[inline]
1185 pub fn ln_gamma(self) -> (f64, i32) {
1186 let mut signgamp: i32 = 0;
1187 let x = cmath::lgamma_r(self, &mut signgamp);
1188 (x, signgamp)
1189 }
1190
1191 /// Error function.
1192 ///
1193 /// # Unspecified precision
1194 ///
1195 /// The precision of this function is non-deterministic. This means it varies by platform,
1196 /// Rust version, and can even differ within the same execution from one invocation to the next.
1197 ///
1198 /// This function currently corresponds to the `erf` from libc on Unix
1199 /// and Windows. Note that this might change in the future.
1200 ///
1201 /// # Examples
1202 ///
1203 /// ```
1204 /// #![feature(float_erf)]
1205 /// /// The error function relates what percent of a normal distribution lies
1206 /// /// within `x` standard deviations (scaled by `1/sqrt(2)`).
1207 /// fn within_standard_deviations(x: f64) -> f64 {
1208 /// (x * std::f64::consts::FRAC_1_SQRT_2).erf() * 100.0
1209 /// }
1210 ///
1211 /// // 68% of a normal distribution is within one standard deviation
1212 /// assert!((within_standard_deviations(1.0) - 68.269).abs() < 0.01);
1213 /// // 95% of a normal distribution is within two standard deviations
1214 /// assert!((within_standard_deviations(2.0) - 95.450).abs() < 0.01);
1215 /// // 99.7% of a normal distribution is within three standard deviations
1216 /// assert!((within_standard_deviations(3.0) - 99.730).abs() < 0.01);
1217 /// ```
1218 #[rustc_allow_incoherent_impl]
1219 #[must_use = "method returns a new number and does not mutate the original value"]
1220 #[unstable(feature = "float_erf", issue = "136321")]
1221 #[inline]
1222 pub fn erf(self) -> f64 {
1223 cmath::erf(self)
1224 }
1225
1226 /// Complementary error function.
1227 ///
1228 /// # Unspecified precision
1229 ///
1230 /// The precision of this function is non-deterministic. This means it varies by platform,
1231 /// Rust version, and can even differ within the same execution from one invocation to the next.
1232 ///
1233 /// This function currently corresponds to the `erfc` from libc on Unix
1234 /// and Windows. Note that this might change in the future.
1235 ///
1236 /// # Examples
1237 ///
1238 /// ```
1239 /// #![feature(float_erf)]
1240 /// let x: f64 = 0.123;
1241 ///
1242 /// let one = x.erf() + x.erfc();
1243 /// let abs_difference = (one - 1.0).abs();
1244 ///
1245 /// assert!(abs_difference <= f64::EPSILON);
1246 /// ```
1247 #[rustc_allow_incoherent_impl]
1248 #[must_use = "method returns a new number and does not mutate the original value"]
1249 #[unstable(feature = "float_erf", issue = "136321")]
1250 #[inline]
1251 pub fn erfc(self) -> f64 {
1252 cmath::erfc(self)
1253 }
1254}