@@ -686,6 +686,182 @@ impl f128 {
686686 self * RADS_PER_DEG
687687 }
688688
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
855+ a + ( b / 2. )
856+ } else if abs_b < LO {
857+ // Not safe to halve b
858+ ( a / 2. ) + b
859+ } else {
860+ // Not safe to halve a and b
861+ ( a / 2. ) + ( b / 2. )
862+ }
863+ }
864+
689865 /// Rounds toward zero and converts to any primitive integer type,
690866 /// assuming that the value is finite and fits in that type.
691867 ///
0 commit comments