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