std/
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")]
8pub use core::f128::consts;
9
10#[cfg(not(test))]
11use crate::intrinsics;
12#[cfg(not(test))]
13use crate::sys::cmath;
14
15#[cfg(not(test))]
16impl f128 {
17    /// Returns the largest integer less than or equal to `self`.
18    ///
19    /// This function always returns the precise result.
20    ///
21    /// # Examples
22    ///
23    /// ```
24    /// #![feature(f128)]
25    /// # #![feature(cfg_target_has_reliable_f16_f128)]
26    /// # #![expect(internal_features)]
27    /// # #[cfg(not(miri))]
28    /// # #[cfg(target_has_reliable_f128_math)] {
29    ///
30    /// let f = 3.7_f128;
31    /// let g = 3.0_f128;
32    /// let h = -3.7_f128;
33    ///
34    /// assert_eq!(f.floor(), 3.0);
35    /// assert_eq!(g.floor(), 3.0);
36    /// assert_eq!(h.floor(), -4.0);
37    /// # }
38    /// ```
39    #[inline]
40    #[rustc_allow_incoherent_impl]
41    #[unstable(feature = "f128", issue = "116909")]
42    #[must_use = "method returns a new number and does not mutate the original value"]
43    pub fn floor(self) -> f128 {
44        unsafe { intrinsics::floorf128(self) }
45    }
46
47    /// Returns the smallest integer greater than or equal to `self`.
48    ///
49    /// This function always returns the precise result.
50    ///
51    /// # Examples
52    ///
53    /// ```
54    /// #![feature(f128)]
55    /// # #![feature(cfg_target_has_reliable_f16_f128)]
56    /// # #![expect(internal_features)]
57    /// # #[cfg(not(miri))]
58    /// # #[cfg(target_has_reliable_f128_math)] {
59    ///
60    /// let f = 3.01_f128;
61    /// let g = 4.0_f128;
62    ///
63    /// assert_eq!(f.ceil(), 4.0);
64    /// assert_eq!(g.ceil(), 4.0);
65    /// # }
66    /// ```
67    #[inline]
68    #[doc(alias = "ceiling")]
69    #[rustc_allow_incoherent_impl]
70    #[unstable(feature = "f128", issue = "116909")]
71    #[must_use = "method returns a new number and does not mutate the original value"]
72    pub fn ceil(self) -> f128 {
73        unsafe { intrinsics::ceilf128(self) }
74    }
75
76    /// Returns the nearest integer to `self`. If a value is half-way between two
77    /// integers, round away from `0.0`.
78    ///
79    /// This function always returns the precise result.
80    ///
81    /// # Examples
82    ///
83    /// ```
84    /// #![feature(f128)]
85    /// # #![feature(cfg_target_has_reliable_f16_f128)]
86    /// # #![expect(internal_features)]
87    /// # #[cfg(not(miri))]
88    /// # #[cfg(target_has_reliable_f128_math)] {
89    ///
90    /// let f = 3.3_f128;
91    /// let g = -3.3_f128;
92    /// let h = -3.7_f128;
93    /// let i = 3.5_f128;
94    /// let j = 4.5_f128;
95    ///
96    /// assert_eq!(f.round(), 3.0);
97    /// assert_eq!(g.round(), -3.0);
98    /// assert_eq!(h.round(), -4.0);
99    /// assert_eq!(i.round(), 4.0);
100    /// assert_eq!(j.round(), 5.0);
101    /// # }
102    /// ```
103    #[inline]
104    #[rustc_allow_incoherent_impl]
105    #[unstable(feature = "f128", issue = "116909")]
106    #[must_use = "method returns a new number and does not mutate the original value"]
107    pub fn round(self) -> f128 {
108        unsafe { intrinsics::roundf128(self) }
109    }
110
111    /// Returns the nearest integer to a number. Rounds half-way cases to the number
112    /// with an even least significant digit.
113    ///
114    /// This function always returns the precise result.
115    ///
116    /// # Examples
117    ///
118    /// ```
119    /// #![feature(f128)]
120    /// # #![feature(cfg_target_has_reliable_f16_f128)]
121    /// # #![expect(internal_features)]
122    /// # #[cfg(not(miri))]
123    /// # #[cfg(target_has_reliable_f128_math)] {
124    ///
125    /// let f = 3.3_f128;
126    /// let g = -3.3_f128;
127    /// let h = 3.5_f128;
128    /// let i = 4.5_f128;
129    ///
130    /// assert_eq!(f.round_ties_even(), 3.0);
131    /// assert_eq!(g.round_ties_even(), -3.0);
132    /// assert_eq!(h.round_ties_even(), 4.0);
133    /// assert_eq!(i.round_ties_even(), 4.0);
134    /// # }
135    /// ```
136    #[inline]
137    #[rustc_allow_incoherent_impl]
138    #[unstable(feature = "f128", issue = "116909")]
139    #[must_use = "method returns a new number and does not mutate the original value"]
140    pub fn round_ties_even(self) -> f128 {
141        intrinsics::round_ties_even_f128(self)
142    }
143
144    /// Returns the integer part of `self`.
145    /// This means that non-integer numbers are always truncated towards zero.
146    ///
147    /// This function always returns the precise result.
148    ///
149    /// # Examples
150    ///
151    /// ```
152    /// #![feature(f128)]
153    /// # #![feature(cfg_target_has_reliable_f16_f128)]
154    /// # #![expect(internal_features)]
155    /// # #[cfg(not(miri))]
156    /// # #[cfg(target_has_reliable_f128_math)] {
157    ///
158    /// let f = 3.7_f128;
159    /// let g = 3.0_f128;
160    /// let h = -3.7_f128;
161    ///
162    /// assert_eq!(f.trunc(), 3.0);
163    /// assert_eq!(g.trunc(), 3.0);
164    /// assert_eq!(h.trunc(), -3.0);
165    /// # }
166    /// ```
167    #[inline]
168    #[doc(alias = "truncate")]
169    #[rustc_allow_incoherent_impl]
170    #[unstable(feature = "f128", issue = "116909")]
171    #[must_use = "method returns a new number and does not mutate the original value"]
172    pub fn trunc(self) -> f128 {
173        unsafe { intrinsics::truncf128(self) }
174    }
175
176    /// Returns the fractional part of `self`.
177    ///
178    /// This function always returns the precise result.
179    ///
180    /// # Examples
181    ///
182    /// ```
183    /// #![feature(f128)]
184    /// # #![feature(cfg_target_has_reliable_f16_f128)]
185    /// # #![expect(internal_features)]
186    /// # #[cfg(not(miri))]
187    /// # #[cfg(target_has_reliable_f128_math)] {
188    ///
189    /// let x = 3.6_f128;
190    /// let y = -3.6_f128;
191    /// let abs_difference_x = (x.fract() - 0.6).abs();
192    /// let abs_difference_y = (y.fract() - (-0.6)).abs();
193    ///
194    /// assert!(abs_difference_x <= f128::EPSILON);
195    /// assert!(abs_difference_y <= f128::EPSILON);
196    /// # }
197    /// ```
198    #[inline]
199    #[rustc_allow_incoherent_impl]
200    #[unstable(feature = "f128", issue = "116909")]
201    #[must_use = "method returns a new number and does not mutate the original value"]
202    pub fn fract(self) -> f128 {
203        self - self.trunc()
204    }
205
206    /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
207    /// error, yielding a more accurate result than an unfused multiply-add.
208    ///
209    /// Using `mul_add` *may* be more performant than an unfused multiply-add if
210    /// the target architecture has a dedicated `fma` CPU instruction. However,
211    /// this is not always true, and will be heavily dependant on designing
212    /// algorithms with specific target hardware in mind.
213    ///
214    /// # Precision
215    ///
216    /// The result of this operation is guaranteed to be the rounded
217    /// infinite-precision result. It is specified by IEEE 754 as
218    /// `fusedMultiplyAdd` and guaranteed not to change.
219    ///
220    /// # Examples
221    ///
222    /// ```
223    /// #![feature(f128)]
224    /// # #![feature(cfg_target_has_reliable_f16_f128)]
225    /// # #![expect(internal_features)]
226    /// # #[cfg(not(miri))]
227    /// # #[cfg(target_has_reliable_f128_math)] {
228    ///
229    /// let m = 10.0_f128;
230    /// let x = 4.0_f128;
231    /// let b = 60.0_f128;
232    ///
233    /// assert_eq!(m.mul_add(x, b), 100.0);
234    /// assert_eq!(m * x + b, 100.0);
235    ///
236    /// let one_plus_eps = 1.0_f128 + f128::EPSILON;
237    /// let one_minus_eps = 1.0_f128 - f128::EPSILON;
238    /// let minus_one = -1.0_f128;
239    ///
240    /// // The exact result (1 + eps) * (1 - eps) = 1 - eps * eps.
241    /// assert_eq!(one_plus_eps.mul_add(one_minus_eps, minus_one), -f128::EPSILON * f128::EPSILON);
242    /// // Different rounding with the non-fused multiply and add.
243    /// assert_eq!(one_plus_eps * one_minus_eps + minus_one, 0.0);
244    /// # }
245    /// ```
246    #[inline]
247    #[rustc_allow_incoherent_impl]
248    #[doc(alias = "fmaf128", alias = "fusedMultiplyAdd")]
249    #[unstable(feature = "f128", issue = "116909")]
250    #[must_use = "method returns a new number and does not mutate the original value"]
251    pub fn mul_add(self, a: f128, b: f128) -> f128 {
252        unsafe { intrinsics::fmaf128(self, a, b) }
253    }
254
255    /// Calculates Euclidean division, the matching method for `rem_euclid`.
256    ///
257    /// This computes the integer `n` such that
258    /// `self = n * rhs + self.rem_euclid(rhs)`.
259    /// In other words, the result is `self / rhs` rounded to the integer `n`
260    /// such that `self >= n * rhs`.
261    ///
262    /// # Precision
263    ///
264    /// The result of this operation is guaranteed to be the rounded
265    /// infinite-precision result.
266    ///
267    /// # Examples
268    ///
269    /// ```
270    /// #![feature(f128)]
271    /// # #![feature(cfg_target_has_reliable_f16_f128)]
272    /// # #![expect(internal_features)]
273    /// # #[cfg(not(miri))]
274    /// # #[cfg(target_has_reliable_f128_math)] {
275    ///
276    /// let a: f128 = 7.0;
277    /// let b = 4.0;
278    /// assert_eq!(a.div_euclid(b), 1.0); // 7.0 > 4.0 * 1.0
279    /// assert_eq!((-a).div_euclid(b), -2.0); // -7.0 >= 4.0 * -2.0
280    /// assert_eq!(a.div_euclid(-b), -1.0); // 7.0 >= -4.0 * -1.0
281    /// assert_eq!((-a).div_euclid(-b), 2.0); // -7.0 >= -4.0 * 2.0
282    /// # }
283    /// ```
284    #[inline]
285    #[rustc_allow_incoherent_impl]
286    #[unstable(feature = "f128", issue = "116909")]
287    #[must_use = "method returns a new number and does not mutate the original value"]
288    pub fn div_euclid(self, rhs: f128) -> f128 {
289        let q = (self / rhs).trunc();
290        if self % rhs < 0.0 {
291            return if rhs > 0.0 { q - 1.0 } else { q + 1.0 };
292        }
293        q
294    }
295
296    /// Calculates the least nonnegative remainder of `self (mod rhs)`.
297    ///
298    /// In particular, the return value `r` satisfies `0.0 <= r < rhs.abs()` in
299    /// most cases. However, due to a floating point round-off error it can
300    /// result in `r == rhs.abs()`, violating the mathematical definition, if
301    /// `self` is much smaller than `rhs.abs()` in magnitude and `self < 0.0`.
302    /// This result is not an element of the function's codomain, but it is the
303    /// closest floating point number in the real numbers and thus fulfills the
304    /// property `self == self.div_euclid(rhs) * rhs + self.rem_euclid(rhs)`
305    /// approximately.
306    ///
307    /// # Precision
308    ///
309    /// The result of this operation is guaranteed to be the rounded
310    /// infinite-precision result.
311    ///
312    /// # Examples
313    ///
314    /// ```
315    /// #![feature(f128)]
316    /// # #![feature(cfg_target_has_reliable_f16_f128)]
317    /// # #![expect(internal_features)]
318    /// # #[cfg(not(miri))]
319    /// # #[cfg(target_has_reliable_f128_math)] {
320    ///
321    /// let a: f128 = 7.0;
322    /// let b = 4.0;
323    /// assert_eq!(a.rem_euclid(b), 3.0);
324    /// assert_eq!((-a).rem_euclid(b), 1.0);
325    /// assert_eq!(a.rem_euclid(-b), 3.0);
326    /// assert_eq!((-a).rem_euclid(-b), 1.0);
327    /// // limitation due to round-off error
328    /// assert!((-f128::EPSILON).rem_euclid(3.0) != 0.0);
329    /// # }
330    /// ```
331    #[inline]
332    #[rustc_allow_incoherent_impl]
333    #[doc(alias = "modulo", alias = "mod")]
334    #[unstable(feature = "f128", issue = "116909")]
335    #[must_use = "method returns a new number and does not mutate the original value"]
336    pub fn rem_euclid(self, rhs: f128) -> f128 {
337        let r = self % rhs;
338        if r < 0.0 { r + rhs.abs() } else { r }
339    }
340
341    /// Raises a number to an integer power.
342    ///
343    /// Using this function is generally faster than using `powf`.
344    /// It might have a different sequence of rounding operations than `powf`,
345    /// so the results are not guaranteed to agree.
346    ///
347    /// # Unspecified precision
348    ///
349    /// The precision of this function is non-deterministic. This means it varies by platform,
350    /// Rust version, and can even differ within the same execution from one invocation to the next.
351    ///
352    /// # Examples
353    ///
354    /// ```
355    /// #![feature(f128)]
356    /// # #![feature(cfg_target_has_reliable_f16_f128)]
357    /// # #![expect(internal_features)]
358    /// # #[cfg(not(miri))]
359    /// # #[cfg(target_has_reliable_f128_math)] {
360    ///
361    /// let x = 2.0_f128;
362    /// let abs_difference = (x.powi(2) - (x * x)).abs();
363    /// assert!(abs_difference <= f128::EPSILON);
364    ///
365    /// assert_eq!(f128::powi(f128::NAN, 0), 1.0);
366    /// # }
367    /// ```
368    #[inline]
369    #[rustc_allow_incoherent_impl]
370    #[unstable(feature = "f128", issue = "116909")]
371    #[must_use = "method returns a new number and does not mutate the original value"]
372    pub fn powi(self, n: i32) -> f128 {
373        unsafe { intrinsics::powif128(self, n) }
374    }
375
376    /// Raises a number to a floating point power.
377    ///
378    /// # Unspecified precision
379    ///
380    /// The precision of this function is non-deterministic. This means it varies by platform,
381    /// Rust version, and can even differ within the same execution from one invocation to the next.
382    ///
383    /// # Examples
384    ///
385    /// ```
386    /// #![feature(f128)]
387    /// # #![feature(cfg_target_has_reliable_f16_f128)]
388    /// # #![expect(internal_features)]
389    /// # #[cfg(not(miri))]
390    /// # #[cfg(target_has_reliable_f128_math)] {
391    ///
392    /// let x = 2.0_f128;
393    /// let abs_difference = (x.powf(2.0) - (x * x)).abs();
394    /// assert!(abs_difference <= f128::EPSILON);
395    ///
396    /// assert_eq!(f128::powf(1.0, f128::NAN), 1.0);
397    /// assert_eq!(f128::powf(f128::NAN, 0.0), 1.0);
398    /// # }
399    /// ```
400    #[inline]
401    #[rustc_allow_incoherent_impl]
402    #[unstable(feature = "f128", issue = "116909")]
403    #[must_use = "method returns a new number and does not mutate the original value"]
404    pub fn powf(self, n: f128) -> f128 {
405        unsafe { intrinsics::powf128(self, n) }
406    }
407
408    /// Returns the square root of a number.
409    ///
410    /// Returns NaN if `self` is a negative number other than `-0.0`.
411    ///
412    /// # Precision
413    ///
414    /// The result of this operation is guaranteed to be the rounded
415    /// infinite-precision result. It is specified by IEEE 754 as `squareRoot`
416    /// and guaranteed not to change.
417    ///
418    /// # Examples
419    ///
420    /// ```
421    /// #![feature(f128)]
422    /// # #![feature(cfg_target_has_reliable_f16_f128)]
423    /// # #![expect(internal_features)]
424    /// # #[cfg(not(miri))]
425    /// # #[cfg(target_has_reliable_f128_math)] {
426    ///
427    /// let positive = 4.0_f128;
428    /// let negative = -4.0_f128;
429    /// let negative_zero = -0.0_f128;
430    ///
431    /// assert_eq!(positive.sqrt(), 2.0);
432    /// assert!(negative.sqrt().is_nan());
433    /// assert!(negative_zero.sqrt() == negative_zero);
434    /// # }
435    /// ```
436    #[inline]
437    #[doc(alias = "squareRoot")]
438    #[rustc_allow_incoherent_impl]
439    #[unstable(feature = "f128", issue = "116909")]
440    #[must_use = "method returns a new number and does not mutate the original value"]
441    pub fn sqrt(self) -> f128 {
442        unsafe { intrinsics::sqrtf128(self) }
443    }
444
445    /// Returns `e^(self)`, (the exponential function).
446    ///
447    /// # Unspecified precision
448    ///
449    /// The precision of this function is non-deterministic. This means it varies by platform,
450    /// Rust version, and can even differ within the same execution from one invocation to the next.
451    ///
452    /// # Examples
453    ///
454    /// ```
455    /// #![feature(f128)]
456    /// # #![feature(cfg_target_has_reliable_f16_f128)]
457    /// # #![expect(internal_features)]
458    /// # #[cfg(not(miri))]
459    /// # #[cfg(target_has_reliable_f128_math)] {
460    ///
461    /// let one = 1.0f128;
462    /// // e^1
463    /// let e = one.exp();
464    ///
465    /// // ln(e) - 1 == 0
466    /// let abs_difference = (e.ln() - 1.0).abs();
467    ///
468    /// assert!(abs_difference <= f128::EPSILON);
469    /// # }
470    /// ```
471    #[inline]
472    #[rustc_allow_incoherent_impl]
473    #[unstable(feature = "f128", issue = "116909")]
474    #[must_use = "method returns a new number and does not mutate the original value"]
475    pub fn exp(self) -> f128 {
476        unsafe { intrinsics::expf128(self) }
477    }
478
479    /// Returns `2^(self)`.
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    /// # Examples
487    ///
488    /// ```
489    /// #![feature(f128)]
490    /// # #![feature(cfg_target_has_reliable_f16_f128)]
491    /// # #![expect(internal_features)]
492    /// # #[cfg(not(miri))]
493    /// # #[cfg(target_has_reliable_f128_math)] {
494    ///
495    /// let f = 2.0f128;
496    ///
497    /// // 2^2 - 4 == 0
498    /// let abs_difference = (f.exp2() - 4.0).abs();
499    ///
500    /// assert!(abs_difference <= f128::EPSILON);
501    /// # }
502    /// ```
503    #[inline]
504    #[rustc_allow_incoherent_impl]
505    #[unstable(feature = "f128", issue = "116909")]
506    #[must_use = "method returns a new number and does not mutate the original value"]
507    pub fn exp2(self) -> f128 {
508        unsafe { intrinsics::exp2f128(self) }
509    }
510
511    /// Returns the natural logarithm of the number.
512    ///
513    /// This returns NaN when the number is negative, and negative infinity when number is zero.
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    /// # Examples
521    ///
522    /// ```
523    /// #![feature(f128)]
524    /// # #![feature(cfg_target_has_reliable_f16_f128)]
525    /// # #![expect(internal_features)]
526    /// # #[cfg(not(miri))]
527    /// # #[cfg(target_has_reliable_f128_math)] {
528    ///
529    /// let one = 1.0f128;
530    /// // e^1
531    /// let e = one.exp();
532    ///
533    /// // ln(e) - 1 == 0
534    /// let abs_difference = (e.ln() - 1.0).abs();
535    ///
536    /// assert!(abs_difference <= f128::EPSILON);
537    /// # }
538    /// ```
539    ///
540    /// Non-positive values:
541    /// ```
542    /// #![feature(f128)]
543    /// # #![feature(cfg_target_has_reliable_f16_f128)]
544    /// # #![expect(internal_features)]
545    /// # #[cfg(not(miri))]
546    /// # #[cfg(target_has_reliable_f128_math)] {
547    ///
548    /// assert_eq!(0_f128.ln(), f128::NEG_INFINITY);
549    /// assert!((-42_f128).ln().is_nan());
550    /// # }
551    /// ```
552    #[inline]
553    #[rustc_allow_incoherent_impl]
554    #[unstable(feature = "f128", issue = "116909")]
555    #[must_use = "method returns a new number and does not mutate the original value"]
556    pub fn ln(self) -> f128 {
557        unsafe { intrinsics::logf128(self) }
558    }
559
560    /// Returns the logarithm of the number with respect to an arbitrary base.
561    ///
562    /// This returns NaN when the number is negative, and negative infinity when number is zero.
563    ///
564    /// The result might not be correctly rounded owing to implementation details;
565    /// `self.log2()` can produce more accurate results for base 2, and
566    /// `self.log10()` can produce more accurate results for base 10.
567    ///
568    /// # Unspecified precision
569    ///
570    /// The precision of this function is non-deterministic. This means it varies by platform,
571    /// Rust version, and can even differ within the same execution from one invocation to the next.
572    ///
573    /// # Examples
574    ///
575    /// ```
576    /// #![feature(f128)]
577    /// # #![feature(cfg_target_has_reliable_f16_f128)]
578    /// # #![expect(internal_features)]
579    /// # #[cfg(not(miri))]
580    /// # #[cfg(target_has_reliable_f128_math)] {
581    ///
582    /// let five = 5.0f128;
583    ///
584    /// // log5(5) - 1 == 0
585    /// let abs_difference = (five.log(5.0) - 1.0).abs();
586    ///
587    /// assert!(abs_difference <= f128::EPSILON);
588    /// # }
589    /// ```
590    ///
591    /// Non-positive values:
592    /// ```
593    /// #![feature(f128)]
594    /// # #![feature(cfg_target_has_reliable_f16_f128)]
595    /// # #![expect(internal_features)]
596    /// # #[cfg(not(miri))]
597    /// # #[cfg(target_has_reliable_f128_math)] {
598    ///
599    /// assert_eq!(0_f128.log(10.0), f128::NEG_INFINITY);
600    /// assert!((-42_f128).log(10.0).is_nan());
601    /// # }
602    /// ```
603    #[inline]
604    #[rustc_allow_incoherent_impl]
605    #[unstable(feature = "f128", issue = "116909")]
606    #[must_use = "method returns a new number and does not mutate the original value"]
607    pub fn log(self, base: f128) -> f128 {
608        self.ln() / base.ln()
609    }
610
611    /// Returns the base 2 logarithm of the number.
612    ///
613    /// This returns NaN when the number is negative, and negative infinity when number is zero.
614    ///
615    /// # Unspecified precision
616    ///
617    /// The precision of this function is non-deterministic. This means it varies by platform,
618    /// Rust version, and can even differ within the same execution from one invocation to the next.
619    ///
620    /// # Examples
621    ///
622    /// ```
623    /// #![feature(f128)]
624    /// # #![feature(cfg_target_has_reliable_f16_f128)]
625    /// # #![expect(internal_features)]
626    /// # #[cfg(not(miri))]
627    /// # #[cfg(target_has_reliable_f128_math)] {
628    ///
629    /// let two = 2.0f128;
630    ///
631    /// // log2(2) - 1 == 0
632    /// let abs_difference = (two.log2() - 1.0).abs();
633    ///
634    /// assert!(abs_difference <= f128::EPSILON);
635    /// # }
636    /// ```
637    ///
638    /// Non-positive values:
639    /// ```
640    /// #![feature(f128)]
641    /// # #![feature(cfg_target_has_reliable_f16_f128)]
642    /// # #![expect(internal_features)]
643    /// # #[cfg(not(miri))]
644    /// # #[cfg(target_has_reliable_f128_math)] {
645    ///
646    /// assert_eq!(0_f128.log2(), f128::NEG_INFINITY);
647    /// assert!((-42_f128).log2().is_nan());
648    /// # }
649    /// ```
650    #[inline]
651    #[rustc_allow_incoherent_impl]
652    #[unstable(feature = "f128", issue = "116909")]
653    #[must_use = "method returns a new number and does not mutate the original value"]
654    pub fn log2(self) -> f128 {
655        unsafe { intrinsics::log2f128(self) }
656    }
657
658    /// Returns the base 10 logarithm of the number.
659    ///
660    /// This returns NaN when the number is negative, and negative infinity when number is zero.
661    ///
662    /// # Unspecified precision
663    ///
664    /// The precision of this function is non-deterministic. This means it varies by platform,
665    /// Rust version, and can even differ within the same execution from one invocation to the next.
666    ///
667    /// # Examples
668    ///
669    /// ```
670    /// #![feature(f128)]
671    /// # #![feature(cfg_target_has_reliable_f16_f128)]
672    /// # #![expect(internal_features)]
673    /// # #[cfg(not(miri))]
674    /// # #[cfg(target_has_reliable_f128_math)] {
675    ///
676    /// let ten = 10.0f128;
677    ///
678    /// // log10(10) - 1 == 0
679    /// let abs_difference = (ten.log10() - 1.0).abs();
680    ///
681    /// assert!(abs_difference <= f128::EPSILON);
682    /// # }
683    /// ```
684    ///
685    /// Non-positive values:
686    /// ```
687    /// #![feature(f128)]
688    /// # #![feature(cfg_target_has_reliable_f16_f128)]
689    /// # #![expect(internal_features)]
690    /// # #[cfg(not(miri))]
691    /// # #[cfg(target_has_reliable_f128_math)] {
692    ///
693    /// assert_eq!(0_f128.log10(), f128::NEG_INFINITY);
694    /// assert!((-42_f128).log10().is_nan());
695    /// # }
696    /// ```
697    #[inline]
698    #[rustc_allow_incoherent_impl]
699    #[unstable(feature = "f128", issue = "116909")]
700    #[must_use = "method returns a new number and does not mutate the original value"]
701    pub fn log10(self) -> f128 {
702        unsafe { intrinsics::log10f128(self) }
703    }
704
705    /// Returns the cube root of a number.
706    ///
707    /// # Unspecified precision
708    ///
709    /// The precision of this function is non-deterministic. This means it varies by platform,
710    /// Rust version, and can even differ within the same execution from one invocation to the next.
711    ///
712    ///
713    /// This function currently corresponds to the `cbrtf128` from libc on Unix
714    /// and Windows. Note that this might change in the future.
715    ///
716    /// # Examples
717    ///
718    /// ```
719    /// #![feature(f128)]
720    /// # #![feature(cfg_target_has_reliable_f16_f128)]
721    /// # #![expect(internal_features)]
722    /// # #[cfg(not(miri))]
723    /// # #[cfg(target_has_reliable_f128_math)] {
724    ///
725    /// let x = 8.0f128;
726    ///
727    /// // x^(1/3) - 2 == 0
728    /// let abs_difference = (x.cbrt() - 2.0).abs();
729    ///
730    /// assert!(abs_difference <= f128::EPSILON);
731    /// # }
732    /// ```
733    #[inline]
734    #[rustc_allow_incoherent_impl]
735    #[unstable(feature = "f128", issue = "116909")]
736    #[must_use = "method returns a new number and does not mutate the original value"]
737    pub fn cbrt(self) -> f128 {
738        cmath::cbrtf128(self)
739    }
740
741    /// Compute the distance between the origin and a point (`x`, `y`) on the
742    /// Euclidean plane. Equivalently, compute the length of the hypotenuse of a
743    /// right-angle triangle with other sides having length `x.abs()` and
744    /// `y.abs()`.
745    ///
746    /// # Unspecified precision
747    ///
748    /// The precision of this function is non-deterministic. This means it varies by platform,
749    /// Rust version, and can even differ within the same execution from one invocation to the next.
750    ///
751    ///
752    /// This function currently corresponds to the `hypotf128` from libc on Unix
753    /// and Windows. Note that this might change in the future.
754    ///
755    /// # Examples
756    ///
757    /// ```
758    /// #![feature(f128)]
759    /// # #![feature(cfg_target_has_reliable_f16_f128)]
760    /// # #![expect(internal_features)]
761    /// # #[cfg(not(miri))]
762    /// # #[cfg(target_has_reliable_f128_math)] {
763    ///
764    /// let x = 2.0f128;
765    /// let y = 3.0f128;
766    ///
767    /// // sqrt(x^2 + y^2)
768    /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs();
769    ///
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 hypot(self, other: f128) -> f128 {
778        cmath::hypotf128(self, other)
779    }
780
781    /// Computes the sine of a number (in radians).
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    /// # Examples
789    ///
790    /// ```
791    /// #![feature(f128)]
792    /// # #![feature(cfg_target_has_reliable_f16_f128)]
793    /// # #![expect(internal_features)]
794    /// # #[cfg(not(miri))]
795    /// # #[cfg(target_has_reliable_f128_math)] {
796    ///
797    /// let x = std::f128::consts::FRAC_PI_2;
798    ///
799    /// let abs_difference = (x.sin() - 1.0).abs();
800    ///
801    /// assert!(abs_difference <= f128::EPSILON);
802    /// # }
803    /// ```
804    #[inline]
805    #[rustc_allow_incoherent_impl]
806    #[unstable(feature = "f128", issue = "116909")]
807    #[must_use = "method returns a new number and does not mutate the original value"]
808    pub fn sin(self) -> f128 {
809        unsafe { intrinsics::sinf128(self) }
810    }
811
812    /// Computes the cosine of a number (in radians).
813    ///
814    /// # Unspecified precision
815    ///
816    /// The precision of this function is non-deterministic. This means it varies by platform,
817    /// Rust version, and can even differ within the same execution from one invocation to the next.
818    ///
819    /// # Examples
820    ///
821    /// ```
822    /// #![feature(f128)]
823    /// # #![feature(cfg_target_has_reliable_f16_f128)]
824    /// # #![expect(internal_features)]
825    /// # #[cfg(not(miri))]
826    /// # #[cfg(target_has_reliable_f128_math)] {
827    ///
828    /// let x = 2.0 * std::f128::consts::PI;
829    ///
830    /// let abs_difference = (x.cos() - 1.0).abs();
831    ///
832    /// assert!(abs_difference <= f128::EPSILON);
833    /// # }
834    /// ```
835    #[inline]
836    #[rustc_allow_incoherent_impl]
837    #[unstable(feature = "f128", issue = "116909")]
838    #[must_use = "method returns a new number and does not mutate the original value"]
839    pub fn cos(self) -> f128 {
840        unsafe { intrinsics::cosf128(self) }
841    }
842
843    /// Computes the tangent of a number (in radians).
844    ///
845    /// # Unspecified precision
846    ///
847    /// The precision of this function is non-deterministic. This means it varies by platform,
848    /// Rust version, and can even differ within the same execution from one invocation to the next.
849    ///
850    /// This function currently corresponds to the `tanf128` from libc on Unix and
851    /// Windows. Note that this might change in the future.
852    ///
853    /// # Examples
854    ///
855    /// ```
856    /// #![feature(f128)]
857    /// # #![feature(cfg_target_has_reliable_f16_f128)]
858    /// # #![expect(internal_features)]
859    /// # #[cfg(not(miri))]
860    /// # #[cfg(target_has_reliable_f128_math)] {
861    ///
862    /// let x = std::f128::consts::FRAC_PI_4;
863    /// let abs_difference = (x.tan() - 1.0).abs();
864    ///
865    /// assert!(abs_difference <= f128::EPSILON);
866    /// # }
867    /// ```
868    #[inline]
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 tan(self) -> f128 {
873        cmath::tanf128(self)
874    }
875
876    /// Computes the arcsine of a number. Return value is in radians in
877    /// the range [-pi/2, pi/2] or NaN if the number is outside the range
878    /// [-1, 1].
879    ///
880    /// # Unspecified precision
881    ///
882    /// The precision of this function is non-deterministic. This means it varies by platform,
883    /// Rust version, and can even differ within the same execution from one invocation to the next.
884    ///
885    /// This function currently corresponds to the `asinf128` from libc on Unix
886    /// and Windows. Note that this might change in the future.
887    ///
888    /// # Examples
889    ///
890    /// ```
891    /// #![feature(f128)]
892    /// # #![feature(cfg_target_has_reliable_f16_f128)]
893    /// # #![expect(internal_features)]
894    /// # #[cfg(not(miri))]
895    /// # #[cfg(target_has_reliable_f128_math)] {
896    ///
897    /// let f = std::f128::consts::FRAC_PI_2;
898    ///
899    /// // asin(sin(pi/2))
900    /// let abs_difference = (f.sin().asin() - std::f128::consts::FRAC_PI_2).abs();
901    ///
902    /// assert!(abs_difference <= f128::EPSILON);
903    /// # }
904    /// ```
905    #[inline]
906    #[doc(alias = "arcsin")]
907    #[rustc_allow_incoherent_impl]
908    #[unstable(feature = "f128", issue = "116909")]
909    #[must_use = "method returns a new number and does not mutate the original value"]
910    pub fn asin(self) -> f128 {
911        cmath::asinf128(self)
912    }
913
914    /// Computes the arccosine of a number. Return value is in radians in
915    /// the range [0, pi] or NaN if the number is outside the range
916    /// [-1, 1].
917    ///
918    /// # Unspecified precision
919    ///
920    /// The precision of this function is non-deterministic. This means it varies by platform,
921    /// Rust version, and can even differ within the same execution from one invocation to the next.
922    ///
923    /// This function currently corresponds to the `acosf128` from libc on Unix
924    /// and Windows. Note that this might change in the future.
925    ///
926    /// # Examples
927    ///
928    /// ```
929    /// #![feature(f128)]
930    /// # #![feature(cfg_target_has_reliable_f16_f128)]
931    /// # #![expect(internal_features)]
932    /// # #[cfg(not(miri))]
933    /// # #[cfg(target_has_reliable_f128_math)] {
934    ///
935    /// let f = std::f128::consts::FRAC_PI_4;
936    ///
937    /// // acos(cos(pi/4))
938    /// let abs_difference = (f.cos().acos() - std::f128::consts::FRAC_PI_4).abs();
939    ///
940    /// assert!(abs_difference <= f128::EPSILON);
941    /// # }
942    /// ```
943    #[inline]
944    #[doc(alias = "arccos")]
945    #[rustc_allow_incoherent_impl]
946    #[unstable(feature = "f128", issue = "116909")]
947    #[must_use = "method returns a new number and does not mutate the original value"]
948    pub fn acos(self) -> f128 {
949        cmath::acosf128(self)
950    }
951
952    /// Computes the arctangent of a number. Return value is in radians in the
953    /// range [-pi/2, pi/2];
954    ///
955    /// # Unspecified precision
956    ///
957    /// The precision of this function is non-deterministic. This means it varies by platform,
958    /// Rust version, and can even differ within the same execution from one invocation to the next.
959    ///
960    /// This function currently corresponds to the `atanf128` from libc on Unix
961    /// and Windows. Note that this might change in the future.
962    ///
963    /// # Examples
964    ///
965    /// ```
966    /// #![feature(f128)]
967    /// # #![feature(cfg_target_has_reliable_f16_f128)]
968    /// # #![expect(internal_features)]
969    /// # #[cfg(not(miri))]
970    /// # #[cfg(target_has_reliable_f128_math)] {
971    ///
972    /// let f = 1.0f128;
973    ///
974    /// // atan(tan(1))
975    /// let abs_difference = (f.tan().atan() - 1.0).abs();
976    ///
977    /// assert!(abs_difference <= f128::EPSILON);
978    /// # }
979    /// ```
980    #[inline]
981    #[doc(alias = "arctan")]
982    #[rustc_allow_incoherent_impl]
983    #[unstable(feature = "f128", issue = "116909")]
984    #[must_use = "method returns a new number and does not mutate the original value"]
985    pub fn atan(self) -> f128 {
986        cmath::atanf128(self)
987    }
988
989    /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`) in radians.
990    ///
991    /// * `x = 0`, `y = 0`: `0`
992    /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]`
993    /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
994    /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
995    ///
996    /// # Unspecified precision
997    ///
998    /// The precision of this function is non-deterministic. This means it varies by platform,
999    /// Rust version, and can even differ within the same execution from one invocation to the next.
1000    ///
1001    /// This function currently corresponds to the `atan2f128` from libc on Unix
1002    /// and Windows. Note that this might change in the future.
1003    ///
1004    /// # Examples
1005    ///
1006    /// ```
1007    /// #![feature(f128)]
1008    /// # #![feature(cfg_target_has_reliable_f16_f128)]
1009    /// # #![expect(internal_features)]
1010    /// # #[cfg(not(miri))]
1011    /// # #[cfg(target_has_reliable_f128_math)] {
1012    ///
1013    /// // Positive angles measured counter-clockwise
1014    /// // from positive x axis
1015    /// // -pi/4 radians (45 deg clockwise)
1016    /// let x1 = 3.0f128;
1017    /// let y1 = -3.0f128;
1018    ///
1019    /// // 3pi/4 radians (135 deg counter-clockwise)
1020    /// let x2 = -3.0f128;
1021    /// let y2 = 3.0f128;
1022    ///
1023    /// let abs_difference_1 = (y1.atan2(x1) - (-std::f128::consts::FRAC_PI_4)).abs();
1024    /// let abs_difference_2 = (y2.atan2(x2) - (3.0 * std::f128::consts::FRAC_PI_4)).abs();
1025    ///
1026    /// assert!(abs_difference_1 <= f128::EPSILON);
1027    /// assert!(abs_difference_2 <= f128::EPSILON);
1028    /// # }
1029    /// ```
1030    #[inline]
1031    #[rustc_allow_incoherent_impl]
1032    #[unstable(feature = "f128", issue = "116909")]
1033    #[must_use = "method returns a new number and does not mutate the original value"]
1034    pub fn atan2(self, other: f128) -> f128 {
1035        cmath::atan2f128(self, other)
1036    }
1037
1038    /// Simultaneously computes the sine and cosine of the number, `x`. Returns
1039    /// `(sin(x), cos(x))`.
1040    ///
1041    /// # Unspecified precision
1042    ///
1043    /// The precision of this function is non-deterministic. This means it varies by platform,
1044    /// Rust version, and can even differ within the same execution from one invocation to the next.
1045    ///
1046    /// This function currently corresponds to the `(f128::sin(x),
1047    /// f128::cos(x))`. Note that this might change in the future.
1048    ///
1049    /// # Examples
1050    ///
1051    /// ```
1052    /// #![feature(f128)]
1053    /// # #![feature(cfg_target_has_reliable_f16_f128)]
1054    /// # #![expect(internal_features)]
1055    /// # #[cfg(not(miri))]
1056    /// # #[cfg(target_has_reliable_f128_math)] {
1057    ///
1058    /// let x = std::f128::consts::FRAC_PI_4;
1059    /// let f = x.sin_cos();
1060    ///
1061    /// let abs_difference_0 = (f.0 - x.sin()).abs();
1062    /// let abs_difference_1 = (f.1 - x.cos()).abs();
1063    ///
1064    /// assert!(abs_difference_0 <= f128::EPSILON);
1065    /// assert!(abs_difference_1 <= f128::EPSILON);
1066    /// # }
1067    /// ```
1068    #[inline]
1069    #[doc(alias = "sincos")]
1070    #[rustc_allow_incoherent_impl]
1071    #[unstable(feature = "f128", issue = "116909")]
1072    pub fn sin_cos(self) -> (f128, f128) {
1073        (self.sin(), self.cos())
1074    }
1075
1076    /// Returns `e^(self) - 1` in a way that is accurate even if the
1077    /// number is close to zero.
1078    ///
1079    /// # Unspecified precision
1080    ///
1081    /// The precision of this function is non-deterministic. This means it varies by platform,
1082    /// Rust version, and can even differ within the same execution from one invocation to the next.
1083    ///
1084    /// This function currently corresponds to the `expm1f128` from libc on Unix
1085    /// and Windows. Note that this might change in the future.
1086    ///
1087    /// # Examples
1088    ///
1089    /// ```
1090    /// #![feature(f128)]
1091    /// # #![feature(cfg_target_has_reliable_f16_f128)]
1092    /// # #![expect(internal_features)]
1093    /// # #[cfg(not(miri))]
1094    /// # #[cfg(target_has_reliable_f128_math)] {
1095    ///
1096    /// let x = 1e-8_f128;
1097    ///
1098    /// // for very small x, e^x is approximately 1 + x + x^2 / 2
1099    /// let approx = x + x * x / 2.0;
1100    /// let abs_difference = (x.exp_m1() - approx).abs();
1101    ///
1102    /// assert!(abs_difference < 1e-10);
1103    /// # }
1104    /// ```
1105    #[inline]
1106    #[rustc_allow_incoherent_impl]
1107    #[unstable(feature = "f128", issue = "116909")]
1108    #[must_use = "method returns a new number and does not mutate the original value"]
1109    pub fn exp_m1(self) -> f128 {
1110        cmath::expm1f128(self)
1111    }
1112
1113    /// Returns `ln(1+n)` (natural logarithm) more accurately than if
1114    /// the operations were performed separately.
1115    ///
1116    /// This returns NaN when `n < -1.0`, and negative infinity when `n == -1.0`.
1117    ///
1118    /// # Unspecified precision
1119    ///
1120    /// The precision of this function is non-deterministic. This means it varies by platform,
1121    /// Rust version, and can even differ within the same execution from one invocation to the next.
1122    ///
1123    /// This function currently corresponds to the `log1pf128` from libc on Unix
1124    /// and Windows. Note that this might change in the future.
1125    ///
1126    /// # Examples
1127    ///
1128    /// ```
1129    /// #![feature(f128)]
1130    /// # #![feature(cfg_target_has_reliable_f16_f128)]
1131    /// # #![expect(internal_features)]
1132    /// # #[cfg(not(miri))]
1133    /// # #[cfg(target_has_reliable_f128_math)] {
1134    ///
1135    /// let x = 1e-8_f128;
1136    ///
1137    /// // for very small x, ln(1 + x) is approximately x - x^2 / 2
1138    /// let approx = x - x * x / 2.0;
1139    /// let abs_difference = (x.ln_1p() - approx).abs();
1140    ///
1141    /// assert!(abs_difference < 1e-10);
1142    /// # }
1143    /// ```
1144    ///
1145    /// Out-of-range values:
1146    /// ```
1147    /// #![feature(f128)]
1148    /// # #![feature(cfg_target_has_reliable_f16_f128)]
1149    /// # #![expect(internal_features)]
1150    /// # #[cfg(not(miri))]
1151    /// # #[cfg(target_has_reliable_f128_math)] {
1152    ///
1153    /// assert_eq!((-1.0_f128).ln_1p(), f128::NEG_INFINITY);
1154    /// assert!((-2.0_f128).ln_1p().is_nan());
1155    /// # }
1156    /// ```
1157    #[inline]
1158    #[doc(alias = "log1p")]
1159    #[must_use = "method returns a new number and does not mutate the original value"]
1160    #[rustc_allow_incoherent_impl]
1161    #[unstable(feature = "f128", issue = "116909")]
1162    pub fn ln_1p(self) -> f128 {
1163        cmath::log1pf128(self)
1164    }
1165
1166    /// Hyperbolic sine function.
1167    ///
1168    /// # Unspecified precision
1169    ///
1170    /// The precision of this function is non-deterministic. This means it varies by platform,
1171    /// Rust version, and can even differ within the same execution from one invocation to the next.
1172    ///
1173    /// This function currently corresponds to the `sinhf128` from libc on Unix
1174    /// and Windows. Note that this might change in the future.
1175    ///
1176    /// # Examples
1177    ///
1178    /// ```
1179    /// #![feature(f128)]
1180    /// # #![feature(cfg_target_has_reliable_f16_f128)]
1181    /// # #![expect(internal_features)]
1182    /// # #[cfg(not(miri))]
1183    /// # #[cfg(target_has_reliable_f128_math)] {
1184    ///
1185    /// let e = std::f128::consts::E;
1186    /// let x = 1.0f128;
1187    ///
1188    /// let f = x.sinh();
1189    /// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
1190    /// let g = ((e * e) - 1.0) / (2.0 * e);
1191    /// let abs_difference = (f - g).abs();
1192    ///
1193    /// assert!(abs_difference <= f128::EPSILON);
1194    /// # }
1195    /// ```
1196    #[inline]
1197    #[rustc_allow_incoherent_impl]
1198    #[unstable(feature = "f128", issue = "116909")]
1199    #[must_use = "method returns a new number and does not mutate the original value"]
1200    pub fn sinh(self) -> f128 {
1201        cmath::sinhf128(self)
1202    }
1203
1204    /// Hyperbolic cosine function.
1205    ///
1206    /// # Unspecified precision
1207    ///
1208    /// The precision of this function is non-deterministic. This means it varies by platform,
1209    /// Rust version, and can even differ within the same execution from one invocation to the next.
1210    ///
1211    /// This function currently corresponds to the `coshf128` from libc on Unix
1212    /// and Windows. Note that this might change in the future.
1213    ///
1214    /// # Examples
1215    ///
1216    /// ```
1217    /// #![feature(f128)]
1218    /// # #![feature(cfg_target_has_reliable_f16_f128)]
1219    /// # #![expect(internal_features)]
1220    /// # #[cfg(not(miri))]
1221    /// # #[cfg(target_has_reliable_f128_math)] {
1222    ///
1223    /// let e = std::f128::consts::E;
1224    /// let x = 1.0f128;
1225    /// let f = x.cosh();
1226    /// // Solving cosh() at 1 gives this result
1227    /// let g = ((e * e) + 1.0) / (2.0 * e);
1228    /// let abs_difference = (f - g).abs();
1229    ///
1230    /// // Same result
1231    /// assert!(abs_difference <= f128::EPSILON);
1232    /// # }
1233    /// ```
1234    #[inline]
1235    #[rustc_allow_incoherent_impl]
1236    #[unstable(feature = "f128", issue = "116909")]
1237    #[must_use = "method returns a new number and does not mutate the original value"]
1238    pub fn cosh(self) -> f128 {
1239        cmath::coshf128(self)
1240    }
1241
1242    /// Hyperbolic tangent function.
1243    ///
1244    /// # Unspecified precision
1245    ///
1246    /// The precision of this function is non-deterministic. This means it varies by platform,
1247    /// Rust version, and can even differ within the same execution from one invocation to the next.
1248    ///
1249    /// This function currently corresponds to the `tanhf128` from libc on Unix
1250    /// and Windows. Note that this might change in the future.
1251    ///
1252    /// # Examples
1253    ///
1254    /// ```
1255    /// #![feature(f128)]
1256    /// # #![feature(cfg_target_has_reliable_f16_f128)]
1257    /// # #![expect(internal_features)]
1258    /// # #[cfg(not(miri))]
1259    /// # #[cfg(target_has_reliable_f128_math)] {
1260    ///
1261    /// let e = std::f128::consts::E;
1262    /// let x = 1.0f128;
1263    ///
1264    /// let f = x.tanh();
1265    /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
1266    /// let g = (1.0 - e.powi(-2)) / (1.0 + e.powi(-2));
1267    /// let abs_difference = (f - g).abs();
1268    ///
1269    /// assert!(abs_difference <= f128::EPSILON);
1270    /// # }
1271    /// ```
1272    #[inline]
1273    #[rustc_allow_incoherent_impl]
1274    #[unstable(feature = "f128", issue = "116909")]
1275    #[must_use = "method returns a new number and does not mutate the original value"]
1276    pub fn tanh(self) -> f128 {
1277        cmath::tanhf128(self)
1278    }
1279
1280    /// Inverse hyperbolic sine function.
1281    ///
1282    /// # Unspecified precision
1283    ///
1284    /// The precision of this function is non-deterministic. This means it varies by platform,
1285    /// Rust version, and can even differ within the same execution from one invocation to the next.
1286    ///
1287    /// # Examples
1288    ///
1289    /// ```
1290    /// #![feature(f128)]
1291    /// # #![feature(cfg_target_has_reliable_f16_f128)]
1292    /// # #![expect(internal_features)]
1293    /// # #[cfg(not(miri))]
1294    /// # #[cfg(target_has_reliable_f128_math)] {
1295    ///
1296    /// let x = 1.0f128;
1297    /// let f = x.sinh().asinh();
1298    ///
1299    /// let abs_difference = (f - x).abs();
1300    ///
1301    /// assert!(abs_difference <= f128::EPSILON);
1302    /// # }
1303    /// ```
1304    #[inline]
1305    #[doc(alias = "arcsinh")]
1306    #[rustc_allow_incoherent_impl]
1307    #[unstable(feature = "f128", issue = "116909")]
1308    #[must_use = "method returns a new number and does not mutate the original value"]
1309    pub fn asinh(self) -> f128 {
1310        let ax = self.abs();
1311        let ix = 1.0 / ax;
1312        (ax + (ax / (Self::hypot(1.0, ix) + ix))).ln_1p().copysign(self)
1313    }
1314
1315    /// Inverse hyperbolic cosine function.
1316    ///
1317    /// # Unspecified precision
1318    ///
1319    /// The precision of this function is non-deterministic. This means it varies by platform,
1320    /// Rust version, and can even differ within the same execution from one invocation to the next.
1321    ///
1322    /// # Examples
1323    ///
1324    /// ```
1325    /// #![feature(f128)]
1326    /// # #![feature(cfg_target_has_reliable_f16_f128)]
1327    /// # #![expect(internal_features)]
1328    /// # #[cfg(not(miri))]
1329    /// # #[cfg(target_has_reliable_f128_math)] {
1330    ///
1331    /// let x = 1.0f128;
1332    /// let f = x.cosh().acosh();
1333    ///
1334    /// let abs_difference = (f - x).abs();
1335    ///
1336    /// assert!(abs_difference <= f128::EPSILON);
1337    /// # }
1338    /// ```
1339    #[inline]
1340    #[doc(alias = "arccosh")]
1341    #[rustc_allow_incoherent_impl]
1342    #[unstable(feature = "f128", issue = "116909")]
1343    #[must_use = "method returns a new number and does not mutate the original value"]
1344    pub fn acosh(self) -> f128 {
1345        if self < 1.0 {
1346            Self::NAN
1347        } else {
1348            (self + ((self - 1.0).sqrt() * (self + 1.0).sqrt())).ln()
1349        }
1350    }
1351
1352    /// Inverse hyperbolic tangent function.
1353    ///
1354    /// # Unspecified precision
1355    ///
1356    /// The precision of this function is non-deterministic. This means it varies by platform,
1357    /// Rust version, and can even differ within the same execution from one invocation to the next.
1358    ///
1359    /// # Examples
1360    ///
1361    /// ```
1362    /// #![feature(f128)]
1363    /// # #![feature(cfg_target_has_reliable_f16_f128)]
1364    /// # #![expect(internal_features)]
1365    /// # #[cfg(not(miri))]
1366    /// # #[cfg(target_has_reliable_f128_math)] {
1367    ///
1368    /// let e = std::f128::consts::E;
1369    /// let f = e.tanh().atanh();
1370    ///
1371    /// let abs_difference = (f - e).abs();
1372    ///
1373    /// assert!(abs_difference <= 1e-5);
1374    /// # }
1375    /// ```
1376    #[inline]
1377    #[doc(alias = "arctanh")]
1378    #[rustc_allow_incoherent_impl]
1379    #[unstable(feature = "f128", issue = "116909")]
1380    #[must_use = "method returns a new number and does not mutate the original value"]
1381    pub fn atanh(self) -> f128 {
1382        0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
1383    }
1384
1385    /// Gamma function.
1386    ///
1387    /// # Unspecified precision
1388    ///
1389    /// The precision of this function is non-deterministic. This means it varies by platform,
1390    /// Rust version, and can even differ within the same execution from one invocation to the next.
1391    ///
1392    /// This function currently corresponds to the `tgammaf128` from libc on Unix
1393    /// and Windows. Note that this might change in the future.
1394    ///
1395    /// # Examples
1396    ///
1397    /// ```
1398    /// #![feature(f128)]
1399    /// #![feature(float_gamma)]
1400    /// # #![feature(cfg_target_has_reliable_f16_f128)]
1401    /// # #![expect(internal_features)]
1402    /// # #[cfg(not(miri))]
1403    /// # #[cfg(target_has_reliable_f128_math)] {
1404    ///
1405    /// let x = 5.0f128;
1406    ///
1407    /// let abs_difference = (x.gamma() - 24.0).abs();
1408    ///
1409    /// assert!(abs_difference <= f128::EPSILON);
1410    /// # }
1411    /// ```
1412    #[inline]
1413    #[rustc_allow_incoherent_impl]
1414    #[unstable(feature = "f128", issue = "116909")]
1415    // #[unstable(feature = "float_gamma", issue = "99842")]
1416    #[must_use = "method returns a new number and does not mutate the original value"]
1417    pub fn gamma(self) -> f128 {
1418        cmath::tgammaf128(self)
1419    }
1420
1421    /// Natural logarithm of the absolute value of the gamma function
1422    ///
1423    /// The integer part of the tuple indicates the sign of the gamma function.
1424    ///
1425    /// # Unspecified precision
1426    ///
1427    /// The precision of this function is non-deterministic. This means it varies by platform,
1428    /// Rust version, and can even differ within the same execution from one invocation to the next.
1429    ///
1430    /// This function currently corresponds to the `lgammaf128_r` from libc on Unix
1431    /// and Windows. Note that this might change in the future.
1432    ///
1433    /// # Examples
1434    ///
1435    /// ```
1436    /// #![feature(f128)]
1437    /// #![feature(float_gamma)]
1438    /// # #![feature(cfg_target_has_reliable_f16_f128)]
1439    /// # #![expect(internal_features)]
1440    /// # #[cfg(not(miri))]
1441    /// # #[cfg(target_has_reliable_f128_math)] {
1442    ///
1443    /// let x = 2.0f128;
1444    ///
1445    /// let abs_difference = (x.ln_gamma().0 - 0.0).abs();
1446    ///
1447    /// assert!(abs_difference <= f128::EPSILON);
1448    /// # }
1449    /// ```
1450    #[inline]
1451    #[rustc_allow_incoherent_impl]
1452    #[unstable(feature = "f128", issue = "116909")]
1453    // #[unstable(feature = "float_gamma", issue = "99842")]
1454    #[must_use = "method returns a new number and does not mutate the original value"]
1455    pub fn ln_gamma(self) -> (f128, i32) {
1456        let mut signgamp: i32 = 0;
1457        let x = cmath::lgammaf128_r(self, &mut signgamp);
1458        (x, signgamp)
1459    }
1460
1461    /// Error function.
1462    ///
1463    /// # Unspecified precision
1464    ///
1465    /// The precision of this function is non-deterministic. This means it varies by platform,
1466    /// Rust version, and can even differ within the same execution from one invocation to the next.
1467    ///
1468    /// This function currently corresponds to the `erff128` from libc on Unix
1469    /// and Windows. Note that this might change in the future.
1470    ///
1471    /// # Examples
1472    ///
1473    /// ```
1474    /// #![feature(f128)]
1475    /// #![feature(float_erf)]
1476    /// # #![feature(cfg_target_has_reliable_f16_f128)]
1477    /// # #![expect(internal_features)]
1478    /// # #[cfg(not(miri))]
1479    /// # #[cfg(target_has_reliable_f128_math)] {
1480    /// /// The error function relates what percent of a normal distribution lies
1481    /// /// within `x` standard deviations (scaled by `1/sqrt(2)`).
1482    /// fn within_standard_deviations(x: f128) -> f128 {
1483    ///     (x * std::f128::consts::FRAC_1_SQRT_2).erf() * 100.0
1484    /// }
1485    ///
1486    /// // 68% of a normal distribution is within one standard deviation
1487    /// assert!((within_standard_deviations(1.0) - 68.269).abs() < 0.01);
1488    /// // 95% of a normal distribution is within two standard deviations
1489    /// assert!((within_standard_deviations(2.0) - 95.450).abs() < 0.01);
1490    /// // 99.7% of a normal distribution is within three standard deviations
1491    /// assert!((within_standard_deviations(3.0) - 99.730).abs() < 0.01);
1492    /// # }
1493    /// ```
1494    #[rustc_allow_incoherent_impl]
1495    #[must_use = "method returns a new number and does not mutate the original value"]
1496    #[unstable(feature = "f128", issue = "116909")]
1497    // #[unstable(feature = "float_erf", issue = "136321")]
1498    #[inline]
1499    pub fn erf(self) -> f128 {
1500        cmath::erff128(self)
1501    }
1502
1503    /// Complementary error function.
1504    ///
1505    /// # Unspecified precision
1506    ///
1507    /// The precision of this function is non-deterministic. This means it varies by platform,
1508    /// Rust version, and can even differ within the same execution from one invocation to the next.
1509    ///
1510    /// This function currently corresponds to the `erfcf128` from libc on Unix
1511    /// and Windows. Note that this might change in the future.
1512    ///
1513    /// # Examples
1514    ///
1515    /// ```
1516    /// #![feature(f128)]
1517    /// #![feature(float_erf)]
1518    /// # #![feature(cfg_target_has_reliable_f16_f128)]
1519    /// # #![expect(internal_features)]
1520    /// # #[cfg(not(miri))]
1521    /// # #[cfg(target_has_reliable_f128_math)] {
1522    /// let x: f128 = 0.123;
1523    ///
1524    /// let one = x.erf() + x.erfc();
1525    /// let abs_difference = (one - 1.0).abs();
1526    ///
1527    /// assert!(abs_difference <= f128::EPSILON);
1528    /// # }
1529    /// ```
1530    #[rustc_allow_incoherent_impl]
1531    #[must_use = "method returns a new number and does not mutate the original value"]
1532    #[unstable(feature = "f128", issue = "116909")]
1533    // #[unstable(feature = "float_erf", issue = "136321")]
1534    #[inline]
1535    pub fn erfc(self) -> f128 {
1536        cmath::erfcf128(self)
1537    }
1538}