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