@@ -686,6 +686,187 @@ 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+ #[ 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+
689870 /// Rounds toward zero and converts to any primitive integer type,
690871 /// assuming that the value is finite and fits in that type.
691872 ///
0 commit comments