@@ -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](f128) 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](f128) 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
///
0 commit comments