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