Skip to content

Commit cfab8ed

Browse files
committed
Reimplement is_sign_negative as a bitcast, libm not necessary.
1 parent 59a1753 commit cfab8ed

File tree

1 file changed

+22
-32
lines changed

1 file changed

+22
-32
lines changed

src/float.rs

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,17 @@ impl FloatCore for f32 {
781781
}
782782
}
783783

784+
#[inline]
785+
#[cfg(not(feature = "std"))]
786+
fn is_sign_negative(self) -> bool {
787+
const SIGN_MASK: u32 = 0x80000000;
788+
789+
// Safety: this identical to the implementation of f32::to_bits(),
790+
// which is only available starting at Rust 1.20
791+
let bits: u32 = unsafe { mem::transmute(self) };
792+
bits & SIGN_MASK != 0
793+
}
794+
784795
#[inline]
785796
#[cfg(not(feature = "std"))]
786797
fn to_degrees(self) -> Self {
@@ -835,22 +846,6 @@ impl FloatCore for f32 {
835846
fn fract(self) -> Self {
836847
self - libm::truncf(self)
837848
}
838-
839-
#[cfg(all(not(feature = "std"), feature = "libm"))]
840-
#[inline]
841-
fn is_sign_negative(self) -> bool {
842-
libm::copysignf(1.0f32, self) == -1.0f32
843-
}
844-
845-
#[cfg(all(not(feature = "std"), feature = "libm"))]
846-
#[inline]
847-
fn signum(self) -> Self {
848-
if self.is_nan() {
849-
FloatCore::nan()
850-
} else {
851-
libm::copysignf(1.0f32, self)
852-
}
853-
}
854849
}
855850

856851
impl FloatCore for f64 {
@@ -888,6 +883,17 @@ impl FloatCore for f64 {
888883
}
889884
}
890885

886+
#[inline]
887+
#[cfg(not(feature = "std"))]
888+
fn is_sign_negative(self) -> bool {
889+
const SIGN_MASK: u64 = 0x8000000000000000;
890+
891+
// Safety: this identical to the implementation of f64::to_bits(),
892+
// which is only available starting at Rust 1.20
893+
let bits: u64 = unsafe { mem::transmute(self) };
894+
bits & SIGN_MASK != 0
895+
}
896+
891897
#[inline]
892898
#[cfg(not(feature = "std"))]
893899
fn to_degrees(self) -> Self {
@@ -943,22 +949,6 @@ impl FloatCore for f64 {
943949
fn fract(self) -> Self {
944950
self - libm::trunc(self)
945951
}
946-
947-
#[cfg(all(not(feature = "std"), feature = "libm"))]
948-
#[inline]
949-
fn is_sign_negative(self) -> bool {
950-
libm::copysign(1.0f64, self) == -1.0f64
951-
}
952-
953-
#[cfg(all(not(feature = "std"), feature = "libm"))]
954-
#[inline]
955-
fn signum(self) -> Self {
956-
if self.is_nan() {
957-
FloatCore::nan()
958-
} else {
959-
libm::copysign(1.0f64, self)
960-
}
961-
}
962952
}
963953

964954
// FIXME: these doctests aren't actually helpful, because they're using and

0 commit comments

Comments
 (0)