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