@@ -678,6 +678,104 @@ impl f32 {
678
678
unsafe { mem:: transmute :: < f32 , u32 > ( self ) & 0x8000_0000 != 0 }
679
679
}
680
680
681
+ /// Returns the least number greater than `self`.
682
+ ///
683
+ /// Let `TINY` be the smallest representable positive `f32`. Then,
684
+ /// - if `self.is_nan()`, this returns `self`;
685
+ /// - if `self` is [`NEG_INFINITY`], this returns [`MIN`];
686
+ /// - if `self` is `-TINY`, this returns -0.0;
687
+ /// - if `self` is -0.0 or +0.0, this returns `TINY`;
688
+ /// - if `self` is [`MAX`] or [`INFINITY`], this returns [`INFINITY`];
689
+ /// - otherwise the unique least value greater than `self` is returned.
690
+ ///
691
+ /// The identity `x.next_up() == -(-x).next_down()` holds for all `x`. When `x`
692
+ /// is finite `x == x.next_up().next_down()` also holds.
693
+ ///
694
+ /// ```rust
695
+ /// #![feature(float_next_up_down)]
696
+ /// // f32::EPSILON is the difference between 1.0 and the next number up.
697
+ /// assert_eq!(1.0f32.next_up(), 1.0 + f32::EPSILON);
698
+ /// // But not for most numbers.
699
+ /// assert!(0.1f32.next_up() < 0.1 + f32::EPSILON);
700
+ /// assert_eq!(16777216f32.next_up(), 16777218.0);
701
+ /// ```
702
+ ///
703
+ /// [`NEG_INFINITY`]: Self::NEG_INFINITY
704
+ /// [`INFINITY`]: Self::INFINITY
705
+ /// [`MIN`]: Self::MIN
706
+ /// [`MAX`]: Self::MAX
707
+ #[ unstable( feature = "float_next_up_down" , issue = "none" ) ]
708
+ pub const fn next_up ( self ) -> Self {
709
+ // We must use strictly integer arithmetic to prevent denormals from
710
+ // flushing to zero after an arithmetic operation on some platforms.
711
+ const TINY_BITS : u32 = 0x1 ; // Smallest positive f32.
712
+ const CLEAR_SIGN_MASK : u32 = 0x7fff_ffff ;
713
+
714
+ let bits = self . to_bits ( ) ;
715
+ if self . is_nan ( ) || bits == Self :: INFINITY . to_bits ( ) {
716
+ return self ;
717
+ }
718
+
719
+ let abs = bits & CLEAR_SIGN_MASK ;
720
+ let next_bits = if abs == 0 {
721
+ TINY_BITS
722
+ } else if bits == abs {
723
+ bits + 1
724
+ } else {
725
+ bits - 1
726
+ } ;
727
+ Self :: from_bits ( next_bits)
728
+ }
729
+
730
+ /// Returns the greatest number less than `self`.
731
+ ///
732
+ /// Let `TINY` be the smallest representable positive `f32`. Then,
733
+ /// - if `self.is_nan()`, this returns `self`;
734
+ /// - if `self` is [`INFINITY`], this returns [`MAX`];
735
+ /// - if `self` is `TINY`, this returns 0.0;
736
+ /// - if `self` is -0.0 or +0.0, this returns `-TINY`;
737
+ /// - if `self` is [`MIN`] or [`NEG_INFINITY`], this returns [`NEG_INFINITY`];
738
+ /// - otherwise the unique greatest value less than `self` is returned.
739
+ ///
740
+ /// The identity `x.next_down() == -(-x).next_up()` holds for all `x`. When `x`
741
+ /// is finite `x == x.next_down().next_up()` also holds.
742
+ ///
743
+ /// ```rust
744
+ /// #![feature(float_next_up_down)]
745
+ /// let x = 1.0f32;
746
+ /// // Clamp value into range [0, 1).
747
+ /// let clamped = x.clamp(0.0, 1.0f32.next_down());
748
+ /// assert!(clamped < 1.0);
749
+ /// assert_eq!(clamped.next_up(), 1.0);
750
+ /// ```
751
+ ///
752
+ /// [`NEG_INFINITY`]: Self::NEG_INFINITY
753
+ /// [`INFINITY`]: Self::INFINITY
754
+ /// [`MIN`]: Self::MIN
755
+ /// [`MAX`]: Self::MAX
756
+ #[ unstable( feature = "float_next_up_down" , issue = "none" ) ]
757
+ pub const fn next_down ( self ) -> Self {
758
+ // We must use strictly integer arithmetic to prevent denormals from
759
+ // flushing to zero after an arithmetic operation on some platforms.
760
+ const NEG_TINY_BITS : u32 = 0x8000_0001 ; // Smallest (in magnitude) negative f32.
761
+ const CLEAR_SIGN_MASK : u32 = 0x7fff_ffff ;
762
+
763
+ let bits = self . to_bits ( ) ;
764
+ if self . is_nan ( ) || bits == Self :: NEG_INFINITY . to_bits ( ) {
765
+ return self ;
766
+ }
767
+
768
+ let abs = bits & CLEAR_SIGN_MASK ;
769
+ let next_bits = if abs == 0 {
770
+ NEG_TINY_BITS
771
+ } else if bits == abs {
772
+ bits - 1
773
+ } else {
774
+ bits + 1
775
+ } ;
776
+ Self :: from_bits ( next_bits)
777
+ }
778
+
681
779
/// Takes the reciprocal (inverse) of a number, `1/x`.
682
780
///
683
781
/// ```
0 commit comments