@@ -1366,3 +1366,380 @@ impl f128 {
1366
1366
unsafe { intrinsics:: copysignf128 ( self , sign) }
1367
1367
}
1368
1368
}
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