@@ -620,6 +620,104 @@ impl f32 {
620
620
self . to_bits ( ) & 0x8000_0000 != 0
621
621
}
622
622
623
+ /// Returns the least number greater than `self`.
624
+ ///
625
+ /// Let `TINY` be the smallest representable positive `f32`. Then,
626
+ /// - if `self.is_nan()`, this returns `self`;
627
+ /// - if `self` is [`NEG_INFINITY`], this returns [`MIN`];
628
+ /// - if `self` is `-TINY`, this returns -0.0;
629
+ /// - if `self` is -0.0 or +0.0, this returns `TINY`;
630
+ /// - if `self` is [`MAX`] or [`INFINITY`], this returns [`INFINITY`];
631
+ /// - otherwise the unique least value greater than `self` is returned.
632
+ ///
633
+ /// The identity `x.next_up() == -(-x).next_down()` holds for all `x`. When `x`
634
+ /// is finite `x == x.next_up().next_down()` also holds.
635
+ ///
636
+ /// ```rust
637
+ /// #![feature(float_next_up_down)]
638
+ /// // f32::EPSILON is the difference between 1.0 and the next number up.
639
+ /// assert_eq!(1.0f32.next_up(), 1.0 + f32::EPSILON);
640
+ /// // But not for most numbers.
641
+ /// assert!(0.1f32.next_up() < 0.1 + f32::EPSILON);
642
+ /// assert_eq!(16777216f32.next_up(), 16777218.0);
643
+ /// ```
644
+ ///
645
+ /// [`NEG_INFINITY`]: Self::NEG_INFINITY
646
+ /// [`INFINITY`]: Self::INFINITY
647
+ /// [`MIN`]: Self::MIN
648
+ /// [`MAX`]: Self::MAX
649
+ #[ unstable( feature = "float_next_up_down" , issue = "none" ) ]
650
+ pub const fn next_up ( self ) -> Self {
651
+ // We must use strictly integer arithmetic to prevent denormals from
652
+ // flushing to zero after an arithmetic operation on some platforms.
653
+ const TINY_BITS : u32 = 0x1 ; // Smallest positive f32.
654
+ const CLEAR_SIGN_MASK : u32 = 0x7fff_ffff ;
655
+
656
+ let bits = self . to_bits ( ) ;
657
+ if self . is_nan ( ) || bits == Self :: INFINITY . to_bits ( ) {
658
+ return self ;
659
+ }
660
+
661
+ let abs = bits & CLEAR_SIGN_MASK ;
662
+ let next_bits = if abs == 0 {
663
+ TINY_BITS
664
+ } else if bits == abs {
665
+ bits + 1
666
+ } else {
667
+ bits - 1
668
+ } ;
669
+ Self :: from_bits ( next_bits)
670
+ }
671
+
672
+ /// Returns the greatest number less than `self`.
673
+ ///
674
+ /// Let `TINY` be the smallest representable positive `f32`. Then,
675
+ /// - if `self.is_nan()`, this returns `self`;
676
+ /// - if `self` is [`INFINITY`], this returns [`MAX`];
677
+ /// - if `self` is `TINY`, this returns 0.0;
678
+ /// - if `self` is -0.0 or +0.0, this returns `-TINY`;
679
+ /// - if `self` is [`MIN`] or [`NEG_INFINITY`], this returns [`NEG_INFINITY`];
680
+ /// - otherwise the unique greatest value less than `self` is returned.
681
+ ///
682
+ /// The identity `x.next_down() == -(-x).next_up()` holds for all `x`. When `x`
683
+ /// is finite `x == x.next_down().next_up()` also holds.
684
+ ///
685
+ /// ```rust
686
+ /// #![feature(float_next_up_down)]
687
+ /// let x = 1.0f32;
688
+ /// // Clamp value into range [0, 1).
689
+ /// let clamped = x.clamp(0.0, 1.0f32.next_down());
690
+ /// assert!(clamped < 1.0);
691
+ /// assert_eq!(clamped.next_up(), 1.0);
692
+ /// ```
693
+ ///
694
+ /// [`NEG_INFINITY`]: Self::NEG_INFINITY
695
+ /// [`INFINITY`]: Self::INFINITY
696
+ /// [`MIN`]: Self::MIN
697
+ /// [`MAX`]: Self::MAX
698
+ #[ unstable( feature = "float_next_up_down" , issue = "none" ) ]
699
+ pub const fn next_down ( self ) -> Self {
700
+ // We must use strictly integer arithmetic to prevent denormals from
701
+ // flushing to zero after an arithmetic operation on some platforms.
702
+ const NEG_TINY_BITS : u32 = 0x8000_0001 ; // Smallest (in magnitude) negative f32.
703
+ const CLEAR_SIGN_MASK : u32 = 0x7fff_ffff ;
704
+
705
+ let bits = self . to_bits ( ) ;
706
+ if self . is_nan ( ) || bits == Self :: NEG_INFINITY . to_bits ( ) {
707
+ return self ;
708
+ }
709
+
710
+ let abs = bits & CLEAR_SIGN_MASK ;
711
+ let next_bits = if abs == 0 {
712
+ NEG_TINY_BITS
713
+ } else if bits == abs {
714
+ bits - 1
715
+ } else {
716
+ bits + 1
717
+ } ;
718
+ Self :: from_bits ( next_bits)
719
+ }
720
+
623
721
/// Takes the reciprocal (inverse) of a number, `1/x`.
624
722
///
625
723
/// ```
0 commit comments