Rollup merge of #128417 - tgross35:f16-f128-math, r=dtolnay · patricklam/verify-rust-std@5d7906c (original) (raw)
`@@ -686,6 +686,182 @@ impl f128 {
`
686
686
`self * RADS_PER_DEG
`
687
687
`}
`
688
688
``
``
689
`+
/// Returns the maximum of the two numbers, ignoring NaN.
`
``
690
`+
///
`
``
691
`+
/// If one of the arguments is NaN, then the other argument is returned.
`
``
692
`+
/// This follows the IEEE 754-2008 semantics for maxNum, except for handling of signaling NaNs;
`
``
693
`+
/// this function handles all NaNs the same way and avoids maxNum's problems with associativity.
`
``
694
`+
/// This also matches the behavior of libm’s fmax.
`
``
695
`+
///
`
``
696
/// ```
``
697
`+
/// #![feature(f128)]
`
``
698
`` +
/// # // Using aarch64 because reliable_f128_math
is needed
``
``
699
`+
/// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {
`
``
700
`+
///
`
``
701
`+
/// let x = 1.0f128;
`
``
702
`+
/// let y = 2.0f128;
`
``
703
`+
///
`
``
704
`+
/// assert_eq!(x.max(y), y);
`
``
705
`+
/// # }
`
``
706
/// ```
``
707
`+
#[inline]
`
``
708
`+
#[unstable(feature = "f128", issue = "116909")]
`
``
709
`+
#[must_use = "this returns the result of the comparison, without modifying either input"]
`
``
710
`+
pub fn max(self, other: f128) -> f128 {
`
``
711
`+
intrinsics::maxnumf128(self, other)
`
``
712
`+
}
`
``
713
+
``
714
`+
/// Returns the minimum of the two numbers, ignoring NaN.
`
``
715
`+
///
`
``
716
`+
/// If one of the arguments is NaN, then the other argument is returned.
`
``
717
`+
/// This follows the IEEE 754-2008 semantics for minNum, except for handling of signaling NaNs;
`
``
718
`+
/// this function handles all NaNs the same way and avoids minNum's problems with associativity.
`
``
719
`+
/// This also matches the behavior of libm’s fmin.
`
``
720
`+
///
`
``
721
/// ```
``
722
`+
/// #![feature(f128)]
`
``
723
`` +
/// # // Using aarch64 because reliable_f128_math
is needed
``
``
724
`+
/// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {
`
``
725
`+
///
`
``
726
`+
/// let x = 1.0f128;
`
``
727
`+
/// let y = 2.0f128;
`
``
728
`+
///
`
``
729
`+
/// assert_eq!(x.min(y), x);
`
``
730
`+
/// # }
`
``
731
/// ```
``
732
`+
#[inline]
`
``
733
`+
#[unstable(feature = "f128", issue = "116909")]
`
``
734
`+
#[must_use = "this returns the result of the comparison, without modifying either input"]
`
``
735
`+
pub fn min(self, other: f128) -> f128 {
`
``
736
`+
intrinsics::minnumf128(self, other)
`
``
737
`+
}
`
``
738
+
``
739
`+
/// Returns the maximum of the two numbers, propagating NaN.
`
``
740
`+
///
`
``
741
`+
/// This returns NaN when either argument is NaN, as opposed to
`
``
742
`` +
/// [f128::max
] which only returns NaN when both arguments are NaN.
``
``
743
`+
///
`
``
744
/// ```
``
745
`+
/// #![feature(f128)]
`
``
746
`+
/// #![feature(float_minimum_maximum)]
`
``
747
`` +
/// # // Using aarch64 because reliable_f128_math
is needed
``
``
748
`+
/// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {
`
``
749
`+
///
`
``
750
`+
/// let x = 1.0f128;
`
``
751
`+
/// let y = 2.0f128;
`
``
752
`+
///
`
``
753
`+
/// assert_eq!(x.maximum(y), y);
`
``
754
`+
/// assert!(x.maximum(f128::NAN).is_nan());
`
``
755
`+
/// # }
`
``
756
/// ```
``
757
`+
///
`
``
758
`+
/// If one of the arguments is NaN, then NaN is returned. Otherwise this returns the greater
`
``
759
`+
/// of the two numbers. For this operation, -0.0 is considered to be less than +0.0.
`
``
760
`+
/// Note that this follows the semantics specified in IEEE 754-2019.
`
``
761
`+
///
`
``
762
`+
/// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN
`
``
763
`+
/// operand is conserved; see explanation of NaN as a special value for more info.
`
``
764
`+
#[inline]
`
``
765
`+
#[unstable(feature = "f128", issue = "116909")]
`
``
766
`+
// #[unstable(feature = "float_minimum_maximum", issue = "91079")]
`
``
767
`+
#[must_use = "this returns the result of the comparison, without modifying either input"]
`
``
768
`+
pub fn maximum(self, other: f128) -> f128 {
`
``
769
`+
if self > other {
`
``
770
`+
self
`
``
771
`+
} else if other > self {
`
``
772
`+
other
`
``
773
`+
} else if self == other {
`
``
774
`+
if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
`
``
775
`+
} else {
`
``
776
`+
self + other
`
``
777
`+
}
`
``
778
`+
}
`
``
779
+
``
780
`+
/// Returns the minimum of the two numbers, propagating NaN.
`
``
781
`+
///
`
``
782
`+
/// This returns NaN when either argument is NaN, as opposed to
`
``
783
`` +
/// [f128::min
] which only returns NaN when both arguments are NaN.
``
``
784
`+
///
`
``
785
/// ```
``
786
`+
/// #![feature(f128)]
`
``
787
`+
/// #![feature(float_minimum_maximum)]
`
``
788
`` +
/// # // Using aarch64 because reliable_f128_math
is needed
``
``
789
`+
/// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {
`
``
790
`+
///
`
``
791
`+
/// let x = 1.0f128;
`
``
792
`+
/// let y = 2.0f128;
`
``
793
`+
///
`
``
794
`+
/// assert_eq!(x.minimum(y), x);
`
``
795
`+
/// assert!(x.minimum(f128::NAN).is_nan());
`
``
796
`+
/// # }
`
``
797
/// ```
``
798
`+
///
`
``
799
`+
/// If one of the arguments is NaN, then NaN is returned. Otherwise this returns the lesser
`
``
800
`+
/// of the two numbers. For this operation, -0.0 is considered to be less than +0.0.
`
``
801
`+
/// Note that this follows the semantics specified in IEEE 754-2019.
`
``
802
`+
///
`
``
803
`+
/// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN
`
``
804
`+
/// operand is conserved; see explanation of NaN as a special value for more info.
`
``
805
`+
#[inline]
`
``
806
`+
#[unstable(feature = "f128", issue = "116909")]
`
``
807
`+
// #[unstable(feature = "float_minimum_maximum", issue = "91079")]
`
``
808
`+
#[must_use = "this returns the result of the comparison, without modifying either input"]
`
``
809
`+
pub fn minimum(self, other: f128) -> f128 {
`
``
810
`+
if self < other {
`
``
811
`+
self
`
``
812
`+
} else if other < self {
`
``
813
`+
other
`
``
814
`+
} else if self == other {
`
``
815
`+
if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
`
``
816
`+
} else {
`
``
817
`` +
// At least one input is NaN. Use +
to perform NaN propagation and quieting.
``
``
818
`+
self + other
`
``
819
`+
}
`
``
820
`+
}
`
``
821
+
``
822
`` +
/// Calculates the middle point of self
and rhs
.
``
``
823
`+
///
`
``
824
`+
/// This returns NaN when either argument is NaN or if a combination of
`
``
825
`+
/// +inf and -inf is provided as arguments.
`
``
826
`+
///
`
``
827
`+
/// # Examples
`
``
828
`+
///
`
``
829
/// ```
``
830
`+
/// #![feature(f128)]
`
``
831
`+
/// #![feature(num_midpoint)]
`
``
832
`` +
/// # // Using aarch64 because reliable_f128_math
is needed
``
``
833
`+
/// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {
`
``
834
`+
///
`
``
835
`+
/// assert_eq!(1f128.midpoint(4.0), 2.5);
`
``
836
`+
/// assert_eq!((-5.5f128).midpoint(8.0), 1.25);
`
``
837
`+
/// # }
`
``
838
/// ```
``
839
`+
#[inline]
`
``
840
`+
#[unstable(feature = "f128", issue = "116909")]
`
``
841
`+
// #[unstable(feature = "num_midpoint", issue = "110840")]
`
``
842
`+
pub fn midpoint(self, other: f128) -> f128 {
`
``
843
`+
const LO: f128 = f128::MIN_POSITIVE * 2.;
`
``
844
`+
const HI: f128 = f128::MAX / 2.;
`
``
845
+
``
846
`+
let (a, b) = (self, other);
`
``
847
`+
let abs_a = a.abs_private();
`
``
848
`+
let abs_b = b.abs_private();
`
``
849
+
``
850
`+
if abs_a <= HI && abs_b <= HI {
`
``
851
`+
// Overflow is impossible
`
``
852
`+
(a + b) / 2.
`
``
853
`+
} else if abs_a < LO {
`
``
854
`` +
// Not safe to halve a
(would underflow)
``
``
855
`+
a + (b / 2.)
`
``
856
`+
} else if abs_b < LO {
`
``
857
`` +
// Not safe to halve b
(would underflow)
``
``
858
`+
(a / 2.) + b
`
``
859
`+
} else {
`
``
860
`` +
// Safe to halve a
and b
``
``
861
`+
(a / 2.) + (b / 2.)
`
``
862
`+
}
`
``
863
`+
}
`
``
864
+
689
865
`/// Rounds toward zero and converts to any primitive integer type,
`
690
866
`/// assuming that the value is finite and fits in that type.
`
691
867
`///
`