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