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