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