Browse Source

Merge #218

218: Implement is_sign_* and signum methods in terms of bitcasts. r=cuviper a=ElectronicRU

# Rationale

[rust-gpu](/EmbarkStudios/rust-gpu) project uses num-traits directly and via glam. However, integer_decode() function is a bit poisonous for it - it immediately requires both Int16 and Int64 capabilities.

This PR reimplements corresponding functions in terms of libm's copysign. (For some reason, rust's libm is missing signbit - it can be done with a bitcast though, maybe that's actually a better implementation avenue).

Co-authored-by: Alex S <alex0player@gmail.com>
bors[bot] 3 năm trước cách đây
mục cha
commit
96a89e6325
1 tập tin đã thay đổi với 22 bổ sung0 xóa
  1. 22 0
      src/float.rs

+ 22 - 0
src/float.rs

@@ -781,6 +781,17 @@ impl FloatCore for f32 {
         }
     }
 
+    #[inline]
+    #[cfg(not(feature = "std"))]
+    fn is_sign_negative(self) -> bool {
+        const SIGN_MASK: u32 = 0x80000000;
+
+        // Safety: this identical to the implementation of f32::to_bits(),
+        // which is only available starting at Rust 1.20
+        let bits: u32 = unsafe { mem::transmute(self) };
+        bits & SIGN_MASK != 0
+    }
+
     #[inline]
     #[cfg(not(feature = "std"))]
     fn to_degrees(self) -> Self {
@@ -872,6 +883,17 @@ impl FloatCore for f64 {
         }
     }
 
+    #[inline]
+    #[cfg(not(feature = "std"))]
+    fn is_sign_negative(self) -> bool {
+        const SIGN_MASK: u64 = 0x8000000000000000;
+
+        // Safety: this identical to the implementation of f64::to_bits(),
+        // which is only available starting at Rust 1.20
+        let bits: u64 = unsafe { mem::transmute(self) };
+        bits & SIGN_MASK != 0
+    }
+
     #[inline]
     #[cfg(not(feature = "std"))]
     fn to_degrees(self) -> Self {