@@ -652,42 +652,13 @@ impl f32 {
652652 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
653653 #[ rustc_const_unstable( feature = "const_float_classify" , issue = "72505" ) ]
654654 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 ,
691662 }
692663 }
693664
@@ -773,7 +744,7 @@ impl f32 {
773744 #[ inline]
774745 #[ unstable( feature = "float_next_up_down" , issue = "91399" ) ]
775746 #[ 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 {
777748 // Some targets violate Rust's assumption of IEEE semantics, e.g. by flushing
778749 // denormals to zero. This is in general unsound and unsupported, but here
779750 // we do our best to still produce the correct result on such targets.
@@ -822,7 +793,7 @@ impl f32 {
822793 #[ inline]
823794 #[ unstable( feature = "float_next_up_down" , issue = "91399" ) ]
824795 #[ 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 {
826797 // Some targets violate Rust's assumption of IEEE semantics, e.g. by flushing
827798 // denormals to zero. This is in general unsound and unsupported, but here
828799 // we do our best to still produce the correct result on such targets.
@@ -1114,7 +1085,7 @@ impl f32 {
11141085 #[ stable( feature = "float_bits_conv" , since = "1.20.0" ) ]
11151086 #[ rustc_const_unstable( feature = "const_float_bits_conv" , issue = "72447" ) ]
11161087 #[ inline]
1117- pub const fn to_bits ( self ) -> u32 {
1088+ pub const extern "C" fn to_bits ( self ) -> u32 {
11181089 // SAFETY: `u32` is a plain old datatype so we can always transmute to it.
11191090 unsafe { mem:: transmute ( self ) }
11201091 }
0 commit comments