f128.rs - source
Description: Source of the Rust file `library/std/src/num/f128.rs`.

#
std/num/
f128.rs

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