std/num/
f128.rs

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