std/num/
f128.rs

1//! Constants for the `f128` quadruple-precision floating point type.
2//!
3//! *[See also the `f128` primitive type](primitive@f128).*
4//!
5//! Mathematically significant numbers are provided in the `consts` sub-module.
6
7#![unstable(feature = "f128", issue = "116909")]
8#![doc(test(attr(feature(cfg_target_has_reliable_f16_f128), expect(internal_features))))]
9
10#[unstable(feature = "f128", issue = "116909")]
11pub use core::f128::consts;
12
13#[cfg(not(test))]
14use crate::intrinsics;
15#[cfg(not(test))]
16use crate::sys::cmath;
17
18#[cfg(not(test))]
19impl f128 {
20    /// Raises a number to a floating point power.
21    ///
22    /// Note that this function is special in that it can return non-NaN results for NaN inputs. For
23    /// example, `f128::powf(f128::NAN, 0.0)` returns `1.0`. However, if an input is a *signaling*
24    /// NaN, then the result is non-deterministically either a NaN or the result that the
25    /// corresponding quiet NaN would produce.
26    ///
27    /// # Unspecified precision
28    ///
29    /// The precision of this function is non-deterministic. This means it varies by platform,
30    /// Rust version, and can even differ within the same execution from one invocation to the next.
31    ///
32    /// # Examples
33    ///
34    /// ```
35    /// #![feature(f128)]
36    /// # #[cfg(not(miri))]
37    /// # #[cfg(target_has_reliable_f128_math)] {
38    ///
39    /// let x = 2.0_f128;
40    /// let abs_difference = (x.powf(2.0) - (x * x)).abs();
41    /// assert!(abs_difference <= f128::EPSILON);
42    ///
43    /// assert_eq!(f128::powf(1.0, f128::NAN), 1.0);
44    /// assert_eq!(f128::powf(f128::NAN, 0.0), 1.0);
45    /// assert_eq!(f128::powf(0.0, 0.0), 1.0);
46    /// # }
47    /// ```
48    #[inline]
49    #[rustc_allow_incoherent_impl]
50    #[unstable(feature = "f128", issue = "116909")]
51    #[must_use = "method returns a new number and does not mutate the original value"]
52    pub fn powf(self, n: f128) -> f128 {
53        intrinsics::powf128(self, n)
54    }
55
56    /// Returns `e^(self)`, (the exponential function).
57    ///
58    /// # Unspecified precision
59    ///
60    /// The precision of this function is non-deterministic. This means it varies by platform,
61    /// Rust version, and can even differ within the same execution from one invocation to the next.
62    ///
63    /// # Examples
64    ///
65    /// ```
66    /// #![feature(f128)]
67    /// # #[cfg(not(miri))]
68    /// # #[cfg(target_has_reliable_f128_math)] {
69    ///
70    /// let one = 1.0f128;
71    /// // e^1
72    /// let e = one.exp();
73    ///
74    /// // ln(e) - 1 == 0
75    /// let abs_difference = (e.ln() - 1.0).abs();
76    ///
77    /// assert!(abs_difference <= f128::EPSILON);
78    /// # }
79    /// ```
80    #[inline]
81    #[rustc_allow_incoherent_impl]
82    #[unstable(feature = "f128", issue = "116909")]
83    #[must_use = "method returns a new number and does not mutate the original value"]
84    pub fn exp(self) -> f128 {
85        intrinsics::expf128(self)
86    }
87
88    /// Returns `2^(self)`.
89    ///
90    /// # Unspecified precision
91    ///
92    /// The precision of this function is non-deterministic. This means it varies by platform,
93    /// Rust version, and can even differ within the same execution from one invocation to the next.
94    ///
95    /// # Examples
96    ///
97    /// ```
98    /// #![feature(f128)]
99    /// # #[cfg(not(miri))]
100    /// # #[cfg(target_has_reliable_f128_math)] {
101    ///
102    /// let f = 2.0f128;
103    ///
104    /// // 2^2 - 4 == 0
105    /// let abs_difference = (f.exp2() - 4.0).abs();
106    ///
107    /// assert!(abs_difference <= f128::EPSILON);
108    /// # }
109    /// ```
110    #[inline]
111    #[rustc_allow_incoherent_impl]
112    #[unstable(feature = "f128", issue = "116909")]
113    #[must_use = "method returns a new number and does not mutate the original value"]
114    pub fn exp2(self) -> f128 {
115        intrinsics::exp2f128(self)
116    }
117
118    /// Returns the natural logarithm of the number.
119    ///
120    /// This returns NaN when the number is negative, and negative infinity when number is zero.
121    ///
122    /// # Unspecified precision
123    ///
124    /// The precision of this function is non-deterministic. This means it varies by platform,
125    /// Rust version, and can even differ within the same execution from one invocation to the next.
126    ///
127    /// # Examples
128    ///
129    /// ```
130    /// #![feature(f128)]
131    /// # #[cfg(not(miri))]
132    /// # #[cfg(target_has_reliable_f128_math)] {
133    ///
134    /// let one = 1.0f128;
135    /// // e^1
136    /// let e = one.exp();
137    ///
138    /// // ln(e) - 1 == 0
139    /// let abs_difference = (e.ln() - 1.0).abs();
140    ///
141    /// assert!(abs_difference <= f128::EPSILON);
142    /// # }
143    /// ```
144    ///
145    /// Non-positive values:
146    /// ```
147    /// #![feature(f128)]
148    /// # #[cfg(not(miri))]
149    /// # #[cfg(target_has_reliable_f128_math)] {
150    ///
151    /// assert_eq!(0_f128.ln(), f128::NEG_INFINITY);
152    /// assert!((-42_f128).ln().is_nan());
153    /// # }
154    /// ```
155    #[inline]
156    #[rustc_allow_incoherent_impl]
157    #[unstable(feature = "f128", issue = "116909")]
158    #[must_use = "method returns a new number and does not mutate the original value"]
159    pub fn ln(self) -> f128 {
160        intrinsics::logf128(self)
161    }
162
163    /// Returns the logarithm of the number with respect to an arbitrary base.
164    ///
165    /// This returns NaN when the number is negative, and negative infinity when number is zero.
166    ///
167    /// The result might not be correctly rounded owing to implementation details;
168    /// `self.log2()` can produce more accurate results for base 2, and
169    /// `self.log10()` can produce more accurate results for base 10.
170    ///
171    /// # Unspecified precision
172    ///
173    /// The precision of this function is non-deterministic. This means it varies by platform,
174    /// Rust version, and can even differ within the same execution from one invocation to the next.
175    ///
176    /// # Examples
177    ///
178    /// ```
179    /// #![feature(f128)]
180    /// # #[cfg(not(miri))]
181    /// # #[cfg(target_has_reliable_f128_math)] {
182    ///
183    /// let five = 5.0f128;
184    ///
185    /// // log5(5) - 1 == 0
186    /// let abs_difference = (five.log(5.0) - 1.0).abs();
187    ///
188    /// assert!(abs_difference <= f128::EPSILON);
189    /// # }
190    /// ```
191    ///
192    /// Non-positive values:
193    /// ```
194    /// #![feature(f128)]
195    /// # #[cfg(not(miri))]
196    /// # #[cfg(target_has_reliable_f128_math)] {
197    ///
198    /// assert_eq!(0_f128.log(10.0), f128::NEG_INFINITY);
199    /// assert!((-42_f128).log(10.0).is_nan());
200    /// # }
201    /// ```
202    #[inline]
203    #[rustc_allow_incoherent_impl]
204    #[unstable(feature = "f128", issue = "116909")]
205    #[must_use = "method returns a new number and does not mutate the original value"]
206    pub fn log(self, base: f128) -> f128 {
207        self.ln() / base.ln()
208    }
209
210    /// Returns the base 2 logarithm of the number.
211    ///
212    /// This returns NaN when the number is negative, and negative infinity when number is zero.
213    ///
214    /// # Unspecified precision
215    ///
216    /// The precision of this function is non-deterministic. This means it varies by platform,
217    /// Rust version, and can even differ within the same execution from one invocation to the next.
218    ///
219    /// # Examples
220    ///
221    /// ```
222    /// #![feature(f128)]
223    /// # #[cfg(not(miri))]
224    /// # #[cfg(target_has_reliable_f128_math)] {
225    ///
226    /// let two = 2.0f128;
227    ///
228    /// // log2(2) - 1 == 0
229    /// let abs_difference = (two.log2() - 1.0).abs();
230    ///
231    /// assert!(abs_difference <= f128::EPSILON);
232    /// # }
233    /// ```
234    ///
235    /// Non-positive values:
236    /// ```
237    /// #![feature(f128)]
238    /// # #[cfg(not(miri))]
239    /// # #[cfg(target_has_reliable_f128_math)] {
240    ///
241    /// assert_eq!(0_f128.log2(), f128::NEG_INFINITY);
242    /// assert!((-42_f128).log2().is_nan());
243    /// # }
244    /// ```
245    #[inline]
246    #[rustc_allow_incoherent_impl]
247    #[unstable(feature = "f128", issue = "116909")]
248    #[must_use = "method returns a new number and does not mutate the original value"]
249    pub fn log2(self) -> f128 {
250        intrinsics::log2f128(self)
251    }
252
253    /// Returns the base 10 logarithm of the number.
254    ///
255    /// This returns NaN when the number is negative, and negative infinity when number is zero.
256    ///
257    /// # Unspecified precision
258    ///
259    /// The precision of this function is non-deterministic. This means it varies by platform,
260    /// Rust version, and can even differ within the same execution from one invocation to the next.
261    ///
262    /// # Examples
263    ///
264    /// ```
265    /// #![feature(f128)]
266    /// # #[cfg(not(miri))]
267    /// # #[cfg(target_has_reliable_f128_math)] {
268    ///
269    /// let ten = 10.0f128;
270    ///
271    /// // log10(10) - 1 == 0
272    /// let abs_difference = (ten.log10() - 1.0).abs();
273    ///
274    /// assert!(abs_difference <= f128::EPSILON);
275    /// # }
276    /// ```
277    ///
278    /// Non-positive values:
279    /// ```
280    /// #![feature(f128)]
281    /// # #[cfg(not(miri))]
282    /// # #[cfg(target_has_reliable_f128_math)] {
283    ///
284    /// assert_eq!(0_f128.log10(), f128::NEG_INFINITY);
285    /// assert!((-42_f128).log10().is_nan());
286    /// # }
287    /// ```
288    #[inline]
289    #[rustc_allow_incoherent_impl]
290    #[unstable(feature = "f128", issue = "116909")]
291    #[must_use = "method returns a new number and does not mutate the original value"]
292    pub fn log10(self) -> f128 {
293        intrinsics::log10f128(self)
294    }
295
296    /// Returns the cube root of a number.
297    ///
298    /// # Unspecified precision
299    ///
300    /// The precision of this function is non-deterministic. This means it varies by platform,
301    /// Rust version, and can even differ within the same execution from one invocation to the next.
302    ///
303    ///
304    /// This function currently corresponds to the `cbrtf128` from libc on Unix
305    /// and Windows. Note that this might change in the future.
306    ///
307    /// # Examples
308    ///
309    /// ```
310    /// #![feature(f128)]
311    /// # #[cfg(not(miri))]
312    /// # #[cfg(target_has_reliable_f128_math)] {
313    ///
314    /// let x = 8.0f128;
315    ///
316    /// // x^(1/3) - 2 == 0
317    /// let abs_difference = (x.cbrt() - 2.0).abs();
318    ///
319    /// assert!(abs_difference <= f128::EPSILON);
320    /// # }
321    /// ```
322    #[inline]
323    #[rustc_allow_incoherent_impl]
324    #[unstable(feature = "f128", issue = "116909")]
325    #[must_use = "method returns a new number and does not mutate the original value"]
326    pub fn cbrt(self) -> f128 {
327        cmath::cbrtf128(self)
328    }
329
330    /// Compute the distance between the origin and a point (`x`, `y`) on the
331    /// Euclidean plane. Equivalently, compute the length of the hypotenuse of a
332    /// right-angle triangle with other sides having length `x.abs()` and
333    /// `y.abs()`.
334    ///
335    /// # Unspecified precision
336    ///
337    /// The precision of this function is non-deterministic. This means it varies by platform,
338    /// Rust version, and can even differ within the same execution from one invocation to the next.
339    ///
340    ///
341    /// This function currently corresponds to the `hypotf128` from libc on Unix
342    /// and Windows. Note that this might change in the future.
343    ///
344    /// # Examples
345    ///
346    /// ```
347    /// #![feature(f128)]
348    /// # #[cfg(not(miri))]
349    /// # #[cfg(target_has_reliable_f128_math)] {
350    ///
351    /// let x = 2.0f128;
352    /// let y = 3.0f128;
353    ///
354    /// // sqrt(x^2 + y^2)
355    /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs();
356    ///
357    /// assert!(abs_difference <= f128::EPSILON);
358    /// # }
359    /// ```
360    #[inline]
361    #[rustc_allow_incoherent_impl]
362    #[unstable(feature = "f128", issue = "116909")]
363    #[must_use = "method returns a new number and does not mutate the original value"]
364    pub fn hypot(self, other: f128) -> f128 {
365        cmath::hypotf128(self, other)
366    }
367
368    /// Computes the sine of a number (in radians).
369    ///
370    /// # Unspecified precision
371    ///
372    /// The precision of this function is non-deterministic. This means it varies by platform,
373    /// Rust version, and can even differ within the same execution from one invocation to the next.
374    ///
375    /// # Examples
376    ///
377    /// ```
378    /// #![feature(f128)]
379    /// # #[cfg(not(miri))]
380    /// # #[cfg(target_has_reliable_f128_math)] {
381    ///
382    /// let x = std::f128::consts::FRAC_PI_2;
383    ///
384    /// let abs_difference = (x.sin() - 1.0).abs();
385    ///
386    /// assert!(abs_difference <= f128::EPSILON);
387    /// # }
388    /// ```
389    #[inline]
390    #[rustc_allow_incoherent_impl]
391    #[unstable(feature = "f128", issue = "116909")]
392    #[must_use = "method returns a new number and does not mutate the original value"]
393    pub fn sin(self) -> f128 {
394        intrinsics::sinf128(self)
395    }
396
397    /// Computes the cosine of a number (in radians).
398    ///
399    /// # Unspecified precision
400    ///
401    /// The precision of this function is non-deterministic. This means it varies by platform,
402    /// Rust version, and can even differ within the same execution from one invocation to the next.
403    ///
404    /// # Examples
405    ///
406    /// ```
407    /// #![feature(f128)]
408    /// # #[cfg(not(miri))]
409    /// # #[cfg(target_has_reliable_f128_math)] {
410    ///
411    /// let x = 2.0 * std::f128::consts::PI;
412    ///
413    /// let abs_difference = (x.cos() - 1.0).abs();
414    ///
415    /// assert!(abs_difference <= f128::EPSILON);
416    /// # }
417    /// ```
418    #[inline]
419    #[rustc_allow_incoherent_impl]
420    #[unstable(feature = "f128", issue = "116909")]
421    #[must_use = "method returns a new number and does not mutate the original value"]
422    pub fn cos(self) -> f128 {
423        intrinsics::cosf128(self)
424    }
425
426    /// Computes the tangent of a number (in radians).
427    ///
428    /// # Unspecified precision
429    ///
430    /// The precision of this function is non-deterministic. This means it varies by platform,
431    /// Rust version, and can even differ within the same execution from one invocation to the next.
432    ///
433    /// This function currently corresponds to the `tanf128` from libc on Unix and
434    /// Windows. Note that this might change in the future.
435    ///
436    /// # Examples
437    ///
438    /// ```
439    /// #![feature(f128)]
440    /// # #[cfg(not(miri))]
441    /// # #[cfg(target_has_reliable_f128_math)] {
442    ///
443    /// let x = std::f128::consts::FRAC_PI_4;
444    /// let abs_difference = (x.tan() - 1.0).abs();
445    ///
446    /// assert!(abs_difference <= f128::EPSILON);
447    /// # }
448    /// ```
449    #[inline]
450    #[rustc_allow_incoherent_impl]
451    #[unstable(feature = "f128", issue = "116909")]
452    #[must_use = "method returns a new number and does not mutate the original value"]
453    pub fn tan(self) -> f128 {
454        cmath::tanf128(self)
455    }
456
457    /// Computes the arcsine of a number. Return value is in radians in
458    /// the range [-pi/2, pi/2] or NaN if the number is outside the range
459    /// [-1, 1].
460    ///
461    /// # Unspecified precision
462    ///
463    /// The precision of this function is non-deterministic. This means it varies by platform,
464    /// Rust version, and can even differ within the same execution from one invocation to the next.
465    ///
466    /// This function currently corresponds to the `asinf128` from libc on Unix
467    /// and Windows. Note that this might change in the future.
468    ///
469    /// # Examples
470    ///
471    /// ```
472    /// #![feature(f128)]
473    /// # #[cfg(not(miri))]
474    /// # #[cfg(target_has_reliable_f128_math)] {
475    ///
476    /// let f = std::f128::consts::FRAC_PI_4;
477    ///
478    /// // asin(sin(pi/2))
479    /// let abs_difference = (f.sin().asin() - f).abs();
480    ///
481    /// assert!(abs_difference <= f128::EPSILON);
482    /// # }
483    /// ```
484    #[inline]
485    #[doc(alias = "arcsin")]
486    #[rustc_allow_incoherent_impl]
487    #[unstable(feature = "f128", issue = "116909")]
488    #[must_use = "method returns a new number and does not mutate the original value"]
489    pub fn asin(self) -> f128 {
490        cmath::asinf128(self)
491    }
492
493    /// Computes the arccosine of a number. Return value is in radians in
494    /// the range [0, pi] or NaN if the number is outside the range
495    /// [-1, 1].
496    ///
497    /// # Unspecified precision
498    ///
499    /// The precision of this function is non-deterministic. This means it varies by platform,
500    /// Rust version, and can even differ within the same execution from one invocation to the next.
501    ///
502    /// This function currently corresponds to the `acosf128` from libc on Unix
503    /// and Windows. Note that this might change in the future.
504    ///
505    /// # Examples
506    ///
507    /// ```
508    /// #![feature(f128)]
509    /// # #[cfg(not(miri))]
510    /// # #[cfg(target_has_reliable_f128_math)] {
511    ///
512    /// let f = std::f128::consts::FRAC_PI_4;
513    ///
514    /// // acos(cos(pi/4))
515    /// let abs_difference = (f.cos().acos() - std::f128::consts::FRAC_PI_4).abs();
516    ///
517    /// assert!(abs_difference <= f128::EPSILON);
518    /// # }
519    /// ```
520    #[inline]
521    #[doc(alias = "arccos")]
522    #[rustc_allow_incoherent_impl]
523    #[unstable(feature = "f128", issue = "116909")]
524    #[must_use = "method returns a new number and does not mutate the original value"]
525    pub fn acos(self) -> f128 {
526        cmath::acosf128(self)
527    }
528
529    /// Computes the arctangent of a number. Return value is in radians in the
530    /// range [-pi/2, pi/2];
531    ///
532    /// # Unspecified precision
533    ///
534    /// The precision of this function is non-deterministic. This means it varies by platform,
535    /// Rust version, and can even differ within the same execution from one invocation to the next.
536    ///
537    /// This function currently corresponds to the `atanf128` from libc on Unix
538    /// and Windows. Note that this might change in the future.
539    ///
540    /// # Examples
541    ///
542    /// ```
543    /// #![feature(f128)]
544    /// # #[cfg(not(miri))]
545    /// # #[cfg(target_has_reliable_f128_math)] {
546    ///
547    /// let f = 1.0f128;
548    ///
549    /// // atan(tan(1))
550    /// let abs_difference = (f.tan().atan() - 1.0).abs();
551    ///
552    /// assert!(abs_difference <= f128::EPSILON);
553    /// # }
554    /// ```
555    #[inline]
556    #[doc(alias = "arctan")]
557    #[rustc_allow_incoherent_impl]
558    #[unstable(feature = "f128", issue = "116909")]
559    #[must_use = "method returns a new number and does not mutate the original value"]
560    pub fn atan(self) -> f128 {
561        cmath::atanf128(self)
562    }
563
564    /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`) in radians.
565    ///
566    ///  | `x`     | `y`     | Piecewise Definition | Range         |
567    ///  |---------|---------|----------------------|---------------|
568    ///  | `>= +0` | `>= +0` | `arctan(y/x)`        | `[+0, +pi/2]` |
569    ///  | `>= +0` | `<= -0` | `arctan(y/x)`        | `[-pi/2, -0]` |
570    ///  | `<= -0` | `>= +0` | `arctan(y/x) + pi`   | `[+pi/2, +pi]`|
571    ///  | `<= -0` | `<= -0` | `arctan(y/x) - pi`   | `[-pi, -pi/2]`|
572    ///
573    /// # Unspecified precision
574    ///
575    /// The precision of this function is non-deterministic. This means it varies by platform,
576    /// Rust version, and can even differ within the same execution from one invocation to the next.
577    ///
578    /// This function currently corresponds to the `atan2f128` from libc on Unix
579    /// and Windows. Note that this might change in the future.
580    ///
581    /// # Examples
582    ///
583    /// ```
584    /// #![feature(f128)]
585    /// # #[cfg(not(miri))]
586    /// # #[cfg(target_has_reliable_f128_math)] {
587    ///
588    /// // Positive angles measured counter-clockwise
589    /// // from positive x axis
590    /// // -pi/4 radians (45 deg clockwise)
591    /// let x1 = 3.0f128;
592    /// let y1 = -3.0f128;
593    ///
594    /// // 3pi/4 radians (135 deg counter-clockwise)
595    /// let x2 = -3.0f128;
596    /// let y2 = 3.0f128;
597    ///
598    /// let abs_difference_1 = (y1.atan2(x1) - (-std::f128::consts::FRAC_PI_4)).abs();
599    /// let abs_difference_2 = (y2.atan2(x2) - (3.0 * std::f128::consts::FRAC_PI_4)).abs();
600    ///
601    /// assert!(abs_difference_1 <= f128::EPSILON);
602    /// assert!(abs_difference_2 <= f128::EPSILON);
603    /// # }
604    /// ```
605    #[inline]
606    #[rustc_allow_incoherent_impl]
607    #[unstable(feature = "f128", issue = "116909")]
608    #[must_use = "method returns a new number and does not mutate the original value"]
609    pub fn atan2(self, other: f128) -> f128 {
610        cmath::atan2f128(self, other)
611    }
612
613    /// Simultaneously computes the sine and cosine of the number, `x`. Returns
614    /// `(sin(x), cos(x))`.
615    ///
616    /// # Unspecified precision
617    ///
618    /// The precision of this function is non-deterministic. This means it varies by platform,
619    /// Rust version, and can even differ within the same execution from one invocation to the next.
620    ///
621    /// This function currently corresponds to the `(f128::sin(x),
622    /// f128::cos(x))`. Note that this might change in the future.
623    ///
624    /// # Examples
625    ///
626    /// ```
627    /// #![feature(f128)]
628    /// # #[cfg(not(miri))]
629    /// # #[cfg(target_has_reliable_f128_math)] {
630    ///
631    /// let x = std::f128::consts::FRAC_PI_4;
632    /// let f = x.sin_cos();
633    ///
634    /// let abs_difference_0 = (f.0 - x.sin()).abs();
635    /// let abs_difference_1 = (f.1 - x.cos()).abs();
636    ///
637    /// assert!(abs_difference_0 <= f128::EPSILON);
638    /// assert!(abs_difference_1 <= f128::EPSILON);
639    /// # }
640    /// ```
641    #[inline]
642    #[doc(alias = "sincos")]
643    #[rustc_allow_incoherent_impl]
644    #[unstable(feature = "f128", issue = "116909")]
645    pub fn sin_cos(self) -> (f128, f128) {
646        (self.sin(), self.cos())
647    }
648
649    /// Returns `e^(self) - 1` in a way that is accurate even if the
650    /// number is close to zero.
651    ///
652    /// # Unspecified precision
653    ///
654    /// The precision of this function is non-deterministic. This means it varies by platform,
655    /// Rust version, and can even differ within the same execution from one invocation to the next.
656    ///
657    /// This function currently corresponds to the `expm1f128` from libc on Unix
658    /// and Windows. Note that this might change in the future.
659    ///
660    /// # Examples
661    ///
662    /// ```
663    /// #![feature(f128)]
664    /// # #[cfg(not(miri))]
665    /// # #[cfg(target_has_reliable_f128_math)] {
666    ///
667    /// let x = 1e-8_f128;
668    ///
669    /// // for very small x, e^x is approximately 1 + x + x^2 / 2
670    /// let approx = x + x * x / 2.0;
671    /// let abs_difference = (x.exp_m1() - approx).abs();
672    ///
673    /// assert!(abs_difference < 1e-10);
674    /// # }
675    /// ```
676    #[inline]
677    #[rustc_allow_incoherent_impl]
678    #[unstable(feature = "f128", issue = "116909")]
679    #[must_use = "method returns a new number and does not mutate the original value"]
680    pub fn exp_m1(self) -> f128 {
681        cmath::expm1f128(self)
682    }
683
684    /// Returns `ln(1+n)` (natural logarithm) more accurately than if
685    /// the operations were performed separately.
686    ///
687    /// This returns NaN when `n < -1.0`, and negative infinity when `n == -1.0`.
688    ///
689    /// # Unspecified precision
690    ///
691    /// The precision of this function is non-deterministic. This means it varies by platform,
692    /// Rust version, and can even differ within the same execution from one invocation to the next.
693    ///
694    /// This function currently corresponds to the `log1pf128` from libc on Unix
695    /// and Windows. Note that this might change in the future.
696    ///
697    /// # Examples
698    ///
699    /// ```
700    /// #![feature(f128)]
701    /// # #[cfg(not(miri))]
702    /// # #[cfg(target_has_reliable_f128_math)] {
703    ///
704    /// let x = 1e-8_f128;
705    ///
706    /// // for very small x, ln(1 + x) is approximately x - x^2 / 2
707    /// let approx = x - x * x / 2.0;
708    /// let abs_difference = (x.ln_1p() - approx).abs();
709    ///
710    /// assert!(abs_difference < 1e-10);
711    /// # }
712    /// ```
713    ///
714    /// Out-of-range values:
715    /// ```
716    /// #![feature(f128)]
717    /// # #[cfg(not(miri))]
718    /// # #[cfg(target_has_reliable_f128_math)] {
719    ///
720    /// assert_eq!((-1.0_f128).ln_1p(), f128::NEG_INFINITY);
721    /// assert!((-2.0_f128).ln_1p().is_nan());
722    /// # }
723    /// ```
724    #[inline]
725    #[doc(alias = "log1p")]
726    #[must_use = "method returns a new number and does not mutate the original value"]
727    #[rustc_allow_incoherent_impl]
728    #[unstable(feature = "f128", issue = "116909")]
729    pub fn ln_1p(self) -> f128 {
730        cmath::log1pf128(self)
731    }
732
733    /// Hyperbolic sine function.
734    ///
735    /// # Unspecified precision
736    ///
737    /// The precision of this function is non-deterministic. This means it varies by platform,
738    /// Rust version, and can even differ within the same execution from one invocation to the next.
739    ///
740    /// This function currently corresponds to the `sinhf128` from libc on Unix
741    /// and Windows. Note that this might change in the future.
742    ///
743    /// # Examples
744    ///
745    /// ```
746    /// #![feature(f128)]
747    /// # #[cfg(not(miri))]
748    /// # #[cfg(target_has_reliable_f128_math)] {
749    ///
750    /// let e = std::f128::consts::E;
751    /// let x = 1.0f128;
752    ///
753    /// let f = x.sinh();
754    /// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
755    /// let g = ((e * e) - 1.0) / (2.0 * e);
756    /// let abs_difference = (f - g).abs();
757    ///
758    /// assert!(abs_difference <= f128::EPSILON);
759    /// # }
760    /// ```
761    #[inline]
762    #[rustc_allow_incoherent_impl]
763    #[unstable(feature = "f128", issue = "116909")]
764    #[must_use = "method returns a new number and does not mutate the original value"]
765    pub fn sinh(self) -> f128 {
766        cmath::sinhf128(self)
767    }
768
769    /// Hyperbolic cosine function.
770    ///
771    /// # Unspecified precision
772    ///
773    /// The precision of this function is non-deterministic. This means it varies by platform,
774    /// Rust version, and can even differ within the same execution from one invocation to the next.
775    ///
776    /// This function currently corresponds to the `coshf128` from libc on Unix
777    /// and Windows. Note that this might change in the future.
778    ///
779    /// # Examples
780    ///
781    /// ```
782    /// #![feature(f128)]
783    /// # #[cfg(not(miri))]
784    /// # #[cfg(target_has_reliable_f128_math)] {
785    ///
786    /// let e = std::f128::consts::E;
787    /// let x = 1.0f128;
788    /// let f = x.cosh();
789    /// // Solving cosh() at 1 gives this result
790    /// let g = ((e * e) + 1.0) / (2.0 * e);
791    /// let abs_difference = (f - g).abs();
792    ///
793    /// // Same result
794    /// assert!(abs_difference <= f128::EPSILON);
795    /// # }
796    /// ```
797    #[inline]
798    #[rustc_allow_incoherent_impl]
799    #[unstable(feature = "f128", issue = "116909")]
800    #[must_use = "method returns a new number and does not mutate the original value"]
801    pub fn cosh(self) -> f128 {
802        cmath::coshf128(self)
803    }
804
805    /// Hyperbolic tangent function.
806    ///
807    /// # Unspecified precision
808    ///
809    /// The precision of this function is non-deterministic. This means it varies by platform,
810    /// Rust version, and can even differ within the same execution from one invocation to the next.
811    ///
812    /// This function currently corresponds to the `tanhf128` from libc on Unix
813    /// and Windows. Note that this might change in the future.
814    ///
815    /// # Examples
816    ///
817    /// ```
818    /// #![feature(f128)]
819    /// # #[cfg(not(miri))]
820    /// # #[cfg(target_has_reliable_f128_math)] {
821    ///
822    /// let e = std::f128::consts::E;
823    /// let x = 1.0f128;
824    ///
825    /// let f = x.tanh();
826    /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
827    /// let g = (1.0 - e.powi(-2)) / (1.0 + e.powi(-2));
828    /// let abs_difference = (f - g).abs();
829    ///
830    /// assert!(abs_difference <= f128::EPSILON);
831    /// # }
832    /// ```
833    #[inline]
834    #[rustc_allow_incoherent_impl]
835    #[unstable(feature = "f128", issue = "116909")]
836    #[must_use = "method returns a new number and does not mutate the original value"]
837    pub fn tanh(self) -> f128 {
838        cmath::tanhf128(self)
839    }
840
841    /// Inverse hyperbolic sine function.
842    ///
843    /// # Unspecified precision
844    ///
845    /// The precision of this function is non-deterministic. This means it varies by platform,
846    /// Rust version, and can even differ within the same execution from one invocation to the next.
847    ///
848    /// # Examples
849    ///
850    /// ```
851    /// #![feature(f128)]
852    /// # #[cfg(not(miri))]
853    /// # #[cfg(target_has_reliable_f128_math)] {
854    ///
855    /// let x = 1.0f128;
856    /// let f = x.sinh().asinh();
857    ///
858    /// let abs_difference = (f - x).abs();
859    ///
860    /// assert!(abs_difference <= f128::EPSILON);
861    /// # }
862    /// ```
863    #[inline]
864    #[doc(alias = "arcsinh")]
865    #[rustc_allow_incoherent_impl]
866    #[unstable(feature = "f128", issue = "116909")]
867    #[must_use = "method returns a new number and does not mutate the original value"]
868    pub fn asinh(self) -> f128 {
869        let ax = self.abs();
870        let ix = 1.0 / ax;
871        (ax + (ax / (Self::hypot(1.0, ix) + ix))).ln_1p().copysign(self)
872    }
873
874    /// Inverse hyperbolic cosine function.
875    ///
876    /// # Unspecified precision
877    ///
878    /// The precision of this function is non-deterministic. This means it varies by platform,
879    /// Rust version, and can even differ within the same execution from one invocation to the next.
880    ///
881    /// # Examples
882    ///
883    /// ```
884    /// #![feature(f128)]
885    /// # #[cfg(not(miri))]
886    /// # #[cfg(target_has_reliable_f128_math)] {
887    ///
888    /// let x = 1.0f128;
889    /// let f = x.cosh().acosh();
890    ///
891    /// let abs_difference = (f - x).abs();
892    ///
893    /// assert!(abs_difference <= f128::EPSILON);
894    /// # }
895    /// ```
896    #[inline]
897    #[doc(alias = "arccosh")]
898    #[rustc_allow_incoherent_impl]
899    #[unstable(feature = "f128", issue = "116909")]
900    #[must_use = "method returns a new number and does not mutate the original value"]
901    pub fn acosh(self) -> f128 {
902        if self < 1.0 {
903            Self::NAN
904        } else {
905            (self + ((self - 1.0).sqrt() * (self + 1.0).sqrt())).ln()
906        }
907    }
908
909    /// Inverse hyperbolic tangent function.
910    ///
911    /// # Unspecified precision
912    ///
913    /// The precision of this function is non-deterministic. This means it varies by platform,
914    /// Rust version, and can even differ within the same execution from one invocation to the next.
915    ///
916    /// # Examples
917    ///
918    /// ```
919    /// #![feature(f128)]
920    /// # #[cfg(not(miri))]
921    /// # #[cfg(target_has_reliable_f128_math)] {
922    ///
923    /// let x = std::f128::consts::FRAC_PI_6;
924    /// let f = x.tanh().atanh();
925    ///
926    /// let abs_difference = (f - x).abs();
927    ///
928    /// assert!(abs_difference <= 1e-5);
929    /// # }
930    /// ```
931    #[inline]
932    #[doc(alias = "arctanh")]
933    #[rustc_allow_incoherent_impl]
934    #[unstable(feature = "f128", issue = "116909")]
935    #[must_use = "method returns a new number and does not mutate the original value"]
936    pub fn atanh(self) -> f128 {
937        0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
938    }
939
940    /// Gamma function.
941    ///
942    /// # Unspecified precision
943    ///
944    /// The precision of this function is non-deterministic. This means it varies by platform,
945    /// Rust version, and can even differ within the same execution from one invocation to the next.
946    ///
947    /// This function currently corresponds to the `tgammaf128` from libc on Unix
948    /// and Windows. Note that this might change in the future.
949    ///
950    /// # Examples
951    ///
952    /// ```
953    /// #![feature(f128)]
954    /// #![feature(float_gamma)]
955    /// # #[cfg(not(miri))]
956    /// # #[cfg(target_has_reliable_f128_math)] {
957    ///
958    /// let x = 5.0f128;
959    ///
960    /// let abs_difference = (x.gamma() - 24.0).abs();
961    ///
962    /// assert!(abs_difference <= f128::EPSILON);
963    /// # }
964    /// ```
965    #[inline]
966    #[rustc_allow_incoherent_impl]
967    #[unstable(feature = "f128", issue = "116909")]
968    // #[unstable(feature = "float_gamma", issue = "99842")]
969    #[must_use = "method returns a new number and does not mutate the original value"]
970    pub fn gamma(self) -> f128 {
971        cmath::tgammaf128(self)
972    }
973
974    /// Natural logarithm of the absolute value of the gamma function
975    ///
976    /// The integer part of the tuple indicates the sign of the gamma function.
977    ///
978    /// # Unspecified precision
979    ///
980    /// The precision of this function is non-deterministic. This means it varies by platform,
981    /// Rust version, and can even differ within the same execution from one invocation to the next.
982    ///
983    /// This function currently corresponds to the `lgammaf128_r` from libc on Unix
984    /// and Windows. Note that this might change in the future.
985    ///
986    /// # Examples
987    ///
988    /// ```
989    /// #![feature(f128)]
990    /// #![feature(float_gamma)]
991    /// # #[cfg(not(miri))]
992    /// # #[cfg(target_has_reliable_f128_math)] {
993    ///
994    /// let x = 2.0f128;
995    ///
996    /// let abs_difference = (x.ln_gamma().0 - 0.0).abs();
997    ///
998    /// assert!(abs_difference <= f128::EPSILON);
999    /// # }
1000    /// ```
1001    #[inline]
1002    #[rustc_allow_incoherent_impl]
1003    #[unstable(feature = "f128", issue = "116909")]
1004    // #[unstable(feature = "float_gamma", issue = "99842")]
1005    #[must_use = "method returns a new number and does not mutate the original value"]
1006    pub fn ln_gamma(self) -> (f128, i32) {
1007        let mut signgamp: i32 = 0;
1008        let x = cmath::lgammaf128_r(self, &mut signgamp);
1009        (x, signgamp)
1010    }
1011
1012    /// Error function.
1013    ///
1014    /// # Unspecified precision
1015    ///
1016    /// The precision of this function is non-deterministic. This means it varies by platform,
1017    /// Rust version, and can even differ within the same execution from one invocation to the next.
1018    ///
1019    /// This function currently corresponds to the `erff128` from libc on Unix
1020    /// and Windows. Note that this might change in the future.
1021    ///
1022    /// # Examples
1023    ///
1024    /// ```
1025    /// #![feature(f128)]
1026    /// #![feature(float_erf)]
1027    /// # #[cfg(not(miri))]
1028    /// # #[cfg(target_has_reliable_f128_math)] {
1029    /// /// The error function relates what percent of a normal distribution lies
1030    /// /// within `x` standard deviations (scaled by `1/sqrt(2)`).
1031    /// fn within_standard_deviations(x: f128) -> f128 {
1032    ///     (x * std::f128::consts::FRAC_1_SQRT_2).erf() * 100.0
1033    /// }
1034    ///
1035    /// // 68% of a normal distribution is within one standard deviation
1036    /// assert!((within_standard_deviations(1.0) - 68.269).abs() < 0.01);
1037    /// // 95% of a normal distribution is within two standard deviations
1038    /// assert!((within_standard_deviations(2.0) - 95.450).abs() < 0.01);
1039    /// // 99.7% of a normal distribution is within three standard deviations
1040    /// assert!((within_standard_deviations(3.0) - 99.730).abs() < 0.01);
1041    /// # }
1042    /// ```
1043    #[rustc_allow_incoherent_impl]
1044    #[must_use = "method returns a new number and does not mutate the original value"]
1045    #[unstable(feature = "f128", issue = "116909")]
1046    // #[unstable(feature = "float_erf", issue = "136321")]
1047    #[inline]
1048    pub fn erf(self) -> f128 {
1049        cmath::erff128(self)
1050    }
1051
1052    /// Complementary error function.
1053    ///
1054    /// # Unspecified precision
1055    ///
1056    /// The precision of this function is non-deterministic. This means it varies by platform,
1057    /// Rust version, and can even differ within the same execution from one invocation to the next.
1058    ///
1059    /// This function currently corresponds to the `erfcf128` from libc on Unix
1060    /// and Windows. Note that this might change in the future.
1061    ///
1062    /// # Examples
1063    ///
1064    /// ```
1065    /// #![feature(f128)]
1066    /// #![feature(float_erf)]
1067    /// # #[cfg(not(miri))]
1068    /// # #[cfg(target_has_reliable_f128_math)] {
1069    /// let x: f128 = 0.123;
1070    ///
1071    /// let one = x.erf() + x.erfc();
1072    /// let abs_difference = (one - 1.0).abs();
1073    ///
1074    /// assert!(abs_difference <= f128::EPSILON);
1075    /// # }
1076    /// ```
1077    #[rustc_allow_incoherent_impl]
1078    #[must_use = "method returns a new number and does not mutate the original value"]
1079    #[unstable(feature = "f128", issue = "116909")]
1080    // #[unstable(feature = "float_erf", issue = "136321")]
1081    #[inline]
1082    pub fn erfc(self) -> f128 {
1083        cmath::erfcf128(self)
1084    }
1085}