@@ -652,42 +652,13 @@ impl f32 {
652
652
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
653
653
#[ rustc_const_unstable( feature = "const_float_classify" , issue = "72505" ) ]
654
654
pub const fn classify ( self ) -> FpCategory {
655
- // A previous implementation tried to only use bitmask-based checks,
656
- // using f32::to_bits to transmute the float to its bit repr and match on that.
657
- // If we only cared about being "technically" correct, that's an entirely legit
658
- // implementation.
659
- //
660
- // Unfortunately, there is hardware out there that does not correctly implement the IEEE
661
- // float semantics Rust relies on: x87 uses a too-large mantissa and exponent, and some
662
- // hardware flushes subnormals to zero. These are platforms bugs, and Rust will misbehave on
663
- // such hardware, but we can at least try to make things seem as sane as possible by being
664
- // careful here.
665
- // Cc https://github.com/rust-lang/rust/issues/114479
666
- if self . is_infinite ( ) {
667
- // A value may compare unequal to infinity, despite having a "full" exponent mask.
668
- FpCategory :: Infinite
669
- } else if self . is_nan ( ) {
670
- // And it may not be NaN, as it can simply be an "overextended" finite value.
671
- FpCategory :: Nan
672
- } else {
673
- // However, std can't simply compare to zero to check for zero, either,
674
- // as correctness requires avoiding equality tests that may be Subnormal == -0.0
675
- // because it may be wrong under "denormals are zero" and "flush to zero" modes.
676
- // Most of std's targets don't use those, but they are used for thumbv7neon.
677
- // So, this does use bitpattern matching for the rest. On x87, due to the incorrect
678
- // float codegen on this hardware, this doesn't actually return a right answer for NaN
679
- // because it cannot correctly discern between a floating point NaN, and some normal
680
- // floating point numbers truncated from an x87 FPU -- but we took care of NaN above, so
681
- // we are fine.
682
- // FIXME(jubilee): This probably could at least answer things correctly for Infinity,
683
- // like the f64 version does, but I need to run more checks on how things go on x86.
684
- // I fear losing mantissa data that would have answered that differently.
685
- let b = self . to_bits ( ) ;
686
- match ( b & Self :: MAN_MASK , b & Self :: EXP_MASK ) {
687
- ( 0 , 0 ) => FpCategory :: Zero ,
688
- ( _, 0 ) => FpCategory :: Subnormal ,
689
- _ => FpCategory :: Normal ,
690
- }
655
+ let b = self . to_bits ( ) ;
656
+ match ( b & Self :: MAN_MASK , b & Self :: EXP_MASK ) {
657
+ ( 0 , Self :: EXP_MASK ) => FpCategory :: Infinite ,
658
+ ( _, Self :: EXP_MASK ) => FpCategory :: Nan ,
659
+ ( 0 , 0 ) => FpCategory :: Zero ,
660
+ ( _, 0 ) => FpCategory :: Subnormal ,
661
+ _ => FpCategory :: Normal ,
691
662
}
692
663
}
693
664
@@ -773,7 +744,7 @@ impl f32 {
773
744
#[ inline]
774
745
#[ unstable( feature = "float_next_up_down" , issue = "91399" ) ]
775
746
#[ rustc_const_unstable( feature = "float_next_up_down" , issue = "91399" ) ]
776
- pub const fn next_up ( self ) -> Self {
747
+ pub const extern "C" fn next_up ( self ) -> Self {
777
748
// Some targets violate Rust's assumption of IEEE semantics, e.g. by flushing
778
749
// denormals to zero. This is in general unsound and unsupported, but here
779
750
// we do our best to still produce the correct result on such targets.
@@ -822,7 +793,7 @@ impl f32 {
822
793
#[ inline]
823
794
#[ unstable( feature = "float_next_up_down" , issue = "91399" ) ]
824
795
#[ rustc_const_unstable( feature = "float_next_up_down" , issue = "91399" ) ]
825
- pub const fn next_down ( self ) -> Self {
796
+ pub const extern "C" fn next_down ( self ) -> Self {
826
797
// Some targets violate Rust's assumption of IEEE semantics, e.g. by flushing
827
798
// denormals to zero. This is in general unsound and unsupported, but here
828
799
// we do our best to still produce the correct result on such targets.
@@ -1114,7 +1085,7 @@ impl f32 {
1114
1085
#[ stable( feature = "float_bits_conv" , since = "1.20.0" ) ]
1115
1086
#[ rustc_const_unstable( feature = "const_float_bits_conv" , issue = "72447" ) ]
1116
1087
#[ inline]
1117
- pub const fn to_bits ( self ) -> u32 {
1088
+ pub const extern "C" fn to_bits ( self ) -> u32 {
1118
1089
// SAFETY: `u32` is a plain old datatype so we can always transmute to it.
1119
1090
unsafe { mem:: transmute ( self ) }
1120
1091
}
0 commit comments