@@ -1415,3 +1415,380 @@ impl f128 {
14151415 intrinsics:: frem_algebraic ( self , rhs)
14161416 }
14171417}
1418+
1419+ // Functions in this module fall into `core_float_math`
1420+ // FIXME(f16_f128): all doctests must be gated to platforms that have `long double` === `_Float128`
1421+ // due to https://github.com/llvm/llvm-project/issues/44744. aarch64 linux matches this.
1422+ // #[unstable(feature = "core_float_math", issue = "137578")]
1423+ #[ cfg( not( test) ) ]
1424+ impl f128 {
1425+ /// Returns the largest integer less than or equal to `self`.
1426+ ///
1427+ /// This function always returns the precise result.
1428+ ///
1429+ /// # Examples
1430+ ///
1431+ /// ```
1432+ /// #![feature(f128)]
1433+ /// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {
1434+ ///
1435+ /// let f = 3.7_f128;
1436+ /// let g = 3.0_f128;
1437+ /// let h = -3.7_f128;
1438+ ///
1439+ /// assert_eq!(f.floor(), 3.0);
1440+ /// assert_eq!(g.floor(), 3.0);
1441+ /// assert_eq!(h.floor(), -4.0);
1442+ /// # }
1443+ /// ```
1444+ #[ inline]
1445+ #[ rustc_allow_incoherent_impl]
1446+ #[ unstable( feature = "f128" , issue = "116909" ) ]
1447+ #[ must_use = "method returns a new number and does not mutate the original value" ]
1448+ pub fn floor ( self ) -> f128 {
1449+ // SAFETY: intrinsic with no preconditions
1450+ unsafe { intrinsics:: floorf128 ( self ) }
1451+ }
1452+
1453+ /// Returns the smallest integer greater than or equal to `self`.
1454+ ///
1455+ /// This function always returns the precise result.
1456+ ///
1457+ /// # Examples
1458+ ///
1459+ /// ```
1460+ /// #![feature(f128)]
1461+ /// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {
1462+ ///
1463+ /// let f = 3.01_f128;
1464+ /// let g = 4.0_f128;
1465+ ///
1466+ /// assert_eq!(f.ceil(), 4.0);
1467+ /// assert_eq!(g.ceil(), 4.0);
1468+ /// # }
1469+ /// ```
1470+ #[ inline]
1471+ #[ doc( alias = "ceiling" ) ]
1472+ #[ rustc_allow_incoherent_impl]
1473+ #[ unstable( feature = "f128" , issue = "116909" ) ]
1474+ #[ must_use = "method returns a new number and does not mutate the original value" ]
1475+ pub fn ceil ( self ) -> f128 {
1476+ // SAFETY: intrinsic with no preconditions
1477+ unsafe { intrinsics:: ceilf128 ( self ) }
1478+ }
1479+
1480+ /// Returns the nearest integer to `self`. If a value is half-way between two
1481+ /// integers, round away from `0.0`.
1482+ ///
1483+ /// This function always returns the precise result.
1484+ ///
1485+ /// # Examples
1486+ ///
1487+ /// ```
1488+ /// #![feature(f128)]
1489+ /// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {
1490+ ///
1491+ /// let f = 3.3_f128;
1492+ /// let g = -3.3_f128;
1493+ /// let h = -3.7_f128;
1494+ /// let i = 3.5_f128;
1495+ /// let j = 4.5_f128;
1496+ ///
1497+ /// assert_eq!(f.round(), 3.0);
1498+ /// assert_eq!(g.round(), -3.0);
1499+ /// assert_eq!(h.round(), -4.0);
1500+ /// assert_eq!(i.round(), 4.0);
1501+ /// assert_eq!(j.round(), 5.0);
1502+ /// # }
1503+ /// ```
1504+ #[ inline]
1505+ #[ rustc_allow_incoherent_impl]
1506+ #[ unstable( feature = "f128" , issue = "116909" ) ]
1507+ #[ must_use = "method returns a new number and does not mutate the original value" ]
1508+ pub fn round ( self ) -> f128 {
1509+ // SAFETY: intrinsic with no preconditions
1510+ unsafe { intrinsics:: roundf128 ( self ) }
1511+ }
1512+
1513+ /// Returns the nearest integer to a number. Rounds half-way cases to the number
1514+ /// with an even least significant digit.
1515+ ///
1516+ /// This function always returns the precise result.
1517+ ///
1518+ /// # Examples
1519+ ///
1520+ /// ```
1521+ /// #![feature(f128)]
1522+ /// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {
1523+ ///
1524+ /// let f = 3.3_f128;
1525+ /// let g = -3.3_f128;
1526+ /// let h = 3.5_f128;
1527+ /// let i = 4.5_f128;
1528+ ///
1529+ /// assert_eq!(f.round_ties_even(), 3.0);
1530+ /// assert_eq!(g.round_ties_even(), -3.0);
1531+ /// assert_eq!(h.round_ties_even(), 4.0);
1532+ /// assert_eq!(i.round_ties_even(), 4.0);
1533+ /// # }
1534+ /// ```
1535+ #[ inline]
1536+ #[ rustc_allow_incoherent_impl]
1537+ #[ unstable( feature = "f128" , issue = "116909" ) ]
1538+ #[ must_use = "method returns a new number and does not mutate the original value" ]
1539+ pub fn round_ties_even ( self ) -> f128 {
1540+ intrinsics:: round_ties_even_f128 ( self )
1541+ }
1542+
1543+ /// Returns the integer part of `self`.
1544+ /// This means that non-integer numbers are always truncated towards zero.
1545+ ///
1546+ /// This function always returns the precise result.
1547+ ///
1548+ /// # Examples
1549+ ///
1550+ /// ```
1551+ /// #![feature(f128)]
1552+ /// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {
1553+ ///
1554+ /// let f = 3.7_f128;
1555+ /// let g = 3.0_f128;
1556+ /// let h = -3.7_f128;
1557+ ///
1558+ /// assert_eq!(f.trunc(), 3.0);
1559+ /// assert_eq!(g.trunc(), 3.0);
1560+ /// assert_eq!(h.trunc(), -3.0);
1561+ /// # }
1562+ /// ```
1563+ #[ inline]
1564+ #[ doc( alias = "truncate" ) ]
1565+ #[ rustc_allow_incoherent_impl]
1566+ #[ unstable( feature = "f128" , issue = "116909" ) ]
1567+ #[ must_use = "method returns a new number and does not mutate the original value" ]
1568+ pub fn trunc ( self ) -> f128 {
1569+ // SAFETY: intrinsic with no preconditions
1570+ unsafe { intrinsics:: truncf128 ( self ) }
1571+ }
1572+
1573+ /// Returns the fractional part of `self`.
1574+ ///
1575+ /// This function always returns the precise result.
1576+ ///
1577+ /// # Examples
1578+ ///
1579+ /// ```
1580+ /// #![feature(f128)]
1581+ /// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {
1582+ ///
1583+ /// let x = 3.6_f128;
1584+ /// let y = -3.6_f128;
1585+ /// let abs_difference_x = (x.fract() - 0.6).abs();
1586+ /// let abs_difference_y = (y.fract() - (-0.6)).abs();
1587+ ///
1588+ /// assert!(abs_difference_x <= f128::EPSILON);
1589+ /// assert!(abs_difference_y <= f128::EPSILON);
1590+ /// # }
1591+ /// ```
1592+ #[ inline]
1593+ #[ rustc_allow_incoherent_impl]
1594+ #[ unstable( feature = "f128" , issue = "116909" ) ]
1595+ #[ must_use = "method returns a new number and does not mutate the original value" ]
1596+ pub fn fract ( self ) -> f128 {
1597+ self - self . trunc ( )
1598+ }
1599+
1600+ /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
1601+ /// error, yielding a more accurate result than an unfused multiply-add.
1602+ ///
1603+ /// Using `mul_add` *may* be more performant than an unfused multiply-add if
1604+ /// the target architecture has a dedicated `fma` CPU instruction. However,
1605+ /// this is not always true, and will be heavily dependant on designing
1606+ /// algorithms with specific target hardware in mind.
1607+ ///
1608+ /// # Precision
1609+ ///
1610+ /// The result of this operation is guaranteed to be the rounded
1611+ /// infinite-precision result. It is specified by IEEE 754 as
1612+ /// `fusedMultiplyAdd` and guaranteed not to change.
1613+ ///
1614+ /// # Examples
1615+ ///
1616+ /// ```
1617+ /// #![feature(f128)]
1618+ /// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {
1619+ ///
1620+ /// let m = 10.0_f128;
1621+ /// let x = 4.0_f128;
1622+ /// let b = 60.0_f128;
1623+ ///
1624+ /// assert_eq!(m.mul_add(x, b), 100.0);
1625+ /// assert_eq!(m * x + b, 100.0);
1626+ ///
1627+ /// let one_plus_eps = 1.0_f128 + f128::EPSILON;
1628+ /// let one_minus_eps = 1.0_f128 - f128::EPSILON;
1629+ /// let minus_one = -1.0_f128;
1630+ ///
1631+ /// // The exact result (1 + eps) * (1 - eps) = 1 - eps * eps.
1632+ /// assert_eq!(one_plus_eps.mul_add(one_minus_eps, minus_one), -f128::EPSILON * f128::EPSILON);
1633+ /// // Different rounding with the non-fused multiply and add.
1634+ /// assert_eq!(one_plus_eps * one_minus_eps + minus_one, 0.0);
1635+ /// # }
1636+ /// ```
1637+ #[ inline]
1638+ #[ rustc_allow_incoherent_impl]
1639+ #[ doc( alias = "fmaf128" , alias = "fusedMultiplyAdd" ) ]
1640+ #[ unstable( feature = "f128" , issue = "116909" ) ]
1641+ #[ must_use = "method returns a new number and does not mutate the original value" ]
1642+ pub fn mul_add ( self , a : f128 , b : f128 ) -> f128 {
1643+ // SAFETY: intrinsic with no preconditions
1644+ unsafe { intrinsics:: fmaf128 ( self , a, b) }
1645+ }
1646+
1647+ /// Calculates Euclidean division, the matching method for `rem_euclid`.
1648+ ///
1649+ /// This computes the integer `n` such that
1650+ /// `self = n * rhs + self.rem_euclid(rhs)`.
1651+ /// In other words, the result is `self / rhs` rounded to the integer `n`
1652+ /// such that `self >= n * rhs`.
1653+ ///
1654+ /// # Precision
1655+ ///
1656+ /// The result of this operation is guaranteed to be the rounded
1657+ /// infinite-precision result.
1658+ ///
1659+ /// # Examples
1660+ ///
1661+ /// ```
1662+ /// #![feature(f128)]
1663+ /// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {
1664+ ///
1665+ /// let a: f128 = 7.0;
1666+ /// let b = 4.0;
1667+ /// assert_eq!(a.div_euclid(b), 1.0); // 7.0 > 4.0 * 1.0
1668+ /// assert_eq!((-a).div_euclid(b), -2.0); // -7.0 >= 4.0 * -2.0
1669+ /// assert_eq!(a.div_euclid(-b), -1.0); // 7.0 >= -4.0 * -1.0
1670+ /// assert_eq!((-a).div_euclid(-b), 2.0); // -7.0 >= -4.0 * 2.0
1671+ /// # }
1672+ /// ```
1673+ #[ inline]
1674+ #[ rustc_allow_incoherent_impl]
1675+ #[ unstable( feature = "f128" , issue = "116909" ) ]
1676+ #[ must_use = "method returns a new number and does not mutate the original value" ]
1677+ pub fn div_euclid ( self , rhs : f128 ) -> f128 {
1678+ let q = ( self / rhs) . trunc ( ) ;
1679+ if self % rhs < 0.0 {
1680+ return if rhs > 0.0 { q - 1.0 } else { q + 1.0 } ;
1681+ }
1682+ q
1683+ }
1684+
1685+ /// Calculates the least nonnegative remainder of `self (mod rhs)`.
1686+ ///
1687+ /// In particular, the return value `r` satisfies `0.0 <= r < rhs.abs()` in
1688+ /// most cases. However, due to a floating point round-off error it can
1689+ /// result in `r == rhs.abs()`, violating the mathematical definition, if
1690+ /// `self` is much smaller than `rhs.abs()` in magnitude and `self < 0.0`.
1691+ /// This result is not an element of the function's codomain, but it is the
1692+ /// closest floating point number in the real numbers and thus fulfills the
1693+ /// property `self == self.div_euclid(rhs) * rhs + self.rem_euclid(rhs)`
1694+ /// approximately.
1695+ ///
1696+ /// # Precision
1697+ ///
1698+ /// The result of this operation is guaranteed to be the rounded
1699+ /// infinite-precision result.
1700+ ///
1701+ /// # Examples
1702+ ///
1703+ /// ```
1704+ /// #![feature(f128)]
1705+ /// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {
1706+ ///
1707+ /// let a: f128 = 7.0;
1708+ /// let b = 4.0;
1709+ /// assert_eq!(a.rem_euclid(b), 3.0);
1710+ /// assert_eq!((-a).rem_euclid(b), 1.0);
1711+ /// assert_eq!(a.rem_euclid(-b), 3.0);
1712+ /// assert_eq!((-a).rem_euclid(-b), 1.0);
1713+ /// // limitation due to round-off error
1714+ /// assert!((-f128::EPSILON).rem_euclid(3.0) != 0.0);
1715+ /// # }
1716+ /// ```
1717+ #[ inline]
1718+ #[ rustc_allow_incoherent_impl]
1719+ #[ doc( alias = "modulo" , alias = "mod" ) ]
1720+ #[ unstable( feature = "f128" , issue = "116909" ) ]
1721+ #[ must_use = "method returns a new number and does not mutate the original value" ]
1722+ pub fn rem_euclid ( self , rhs : f128 ) -> f128 {
1723+ let r = self % rhs;
1724+ if r < 0.0 { r + rhs. abs ( ) } else { r }
1725+ }
1726+
1727+ /// Raises a number to an integer power.
1728+ ///
1729+ /// Using this function is generally faster than using `powf`.
1730+ /// It might have a different sequence of rounding operations than `powf`,
1731+ /// so the results are not guaranteed to agree.
1732+ ///
1733+ /// # Unspecified precision
1734+ ///
1735+ /// The precision of this function is non-deterministic. This means it varies by platform,
1736+ /// Rust version, and can even differ within the same execution from one invocation to the next.
1737+ ///
1738+ /// # Examples
1739+ ///
1740+ /// ```
1741+ /// #![feature(f128)]
1742+ /// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {
1743+ ///
1744+ /// let x = 2.0_f128;
1745+ /// let abs_difference = (x.powi(2) - (x * x)).abs();
1746+ /// assert!(abs_difference <= f128::EPSILON);
1747+ ///
1748+ /// assert_eq!(f128::powi(f128::NAN, 0), 1.0);
1749+ /// # }
1750+ /// ```
1751+ #[ inline]
1752+ #[ rustc_allow_incoherent_impl]
1753+ #[ unstable( feature = "f128" , issue = "116909" ) ]
1754+ #[ must_use = "method returns a new number and does not mutate the original value" ]
1755+ pub fn powi ( self , n : i32 ) -> f128 {
1756+ // SAFETY: intrinsic with no preconditions
1757+ unsafe { intrinsics:: powif128 ( self , n) }
1758+ }
1759+
1760+ /// Returns the square root of a number.
1761+ ///
1762+ /// Returns NaN if `self` is a negative number other than `-0.0`.
1763+ ///
1764+ /// # Precision
1765+ ///
1766+ /// The result of this operation is guaranteed to be the rounded
1767+ /// infinite-precision result. It is specified by IEEE 754 as `squareRoot`
1768+ /// and guaranteed not to change.
1769+ ///
1770+ /// # Examples
1771+ ///
1772+ /// ```
1773+ /// #![feature(f128)]
1774+ /// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {
1775+ ///
1776+ /// let positive = 4.0_f128;
1777+ /// let negative = -4.0_f128;
1778+ /// let negative_zero = -0.0_f128;
1779+ ///
1780+ /// assert_eq!(positive.sqrt(), 2.0);
1781+ /// assert!(negative.sqrt().is_nan());
1782+ /// assert!(negative_zero.sqrt() == negative_zero);
1783+ /// # }
1784+ /// ```
1785+ #[ inline]
1786+ #[ doc( alias = "squareRoot" ) ]
1787+ #[ rustc_allow_incoherent_impl]
1788+ #[ unstable( feature = "f128" , issue = "116909" ) ]
1789+ #[ must_use = "method returns a new number and does not mutate the original value" ]
1790+ pub fn sqrt ( self ) -> f128 {
1791+ // SAFETY: intrinsic with no preconditions
1792+ unsafe { intrinsics:: sqrtf128 ( self ) }
1793+ }
1794+ }
0 commit comments