Skip to main content

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