Skip to content

Commit fd601a8

Browse files
committed
Use {float}::to_bits instead of mem::transmute
1 parent a933de0 commit fd601a8

File tree

2 files changed

+24
-39
lines changed

2 files changed

+24
-39
lines changed

src/float.rs

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use core::mem;
21
use core::num::FpCategory;
32
use core::ops::{Add, Div, Neg};
43

@@ -766,9 +765,7 @@ impl FloatCore for f32 {
766765
const EXP_MASK: u32 = 0x7f800000;
767766
const MAN_MASK: u32 = 0x007fffff;
768767

769-
// Safety: this identical to the implementation of f32::to_bits(),
770-
// which is only available starting at Rust 1.20
771-
let bits: u32 = unsafe { mem::transmute(self) };
768+
let bits: u32 = self.to_bits();
772769
match (bits & MAN_MASK, bits & EXP_MASK) {
773770
(0, 0) => FpCategory::Zero,
774771
(_, 0) => FpCategory::Subnormal,
@@ -783,10 +780,7 @@ impl FloatCore for f32 {
783780
fn is_sign_negative(self) -> bool {
784781
const SIGN_MASK: u32 = 0x80000000;
785782

786-
// Safety: this identical to the implementation of f32::to_bits(),
787-
// which is only available starting at Rust 1.20
788-
let bits: u32 = unsafe { mem::transmute(self) };
789-
bits & SIGN_MASK != 0
783+
self.to_bits() & SIGN_MASK != 0
790784
}
791785

792786
#[inline]
@@ -868,9 +862,7 @@ impl FloatCore for f64 {
868862
const EXP_MASK: u64 = 0x7ff0000000000000;
869863
const MAN_MASK: u64 = 0x000fffffffffffff;
870864

871-
// Safety: this identical to the implementation of f64::to_bits(),
872-
// which is only available starting at Rust 1.20
873-
let bits: u64 = unsafe { mem::transmute(self) };
865+
let bits: u64 = self.to_bits();
874866
match (bits & MAN_MASK, bits & EXP_MASK) {
875867
(0, 0) => FpCategory::Zero,
876868
(_, 0) => FpCategory::Subnormal,
@@ -885,10 +877,7 @@ impl FloatCore for f64 {
885877
fn is_sign_negative(self) -> bool {
886878
const SIGN_MASK: u64 = 0x8000000000000000;
887879

888-
// Safety: this identical to the implementation of f64::to_bits(),
889-
// which is only available starting at Rust 1.20
890-
let bits: u64 = unsafe { mem::transmute(self) };
891-
bits & SIGN_MASK != 0
880+
self.to_bits() & SIGN_MASK != 0
892881
}
893882

894883
#[inline]
@@ -2026,9 +2015,7 @@ macro_rules! float_impl_libm {
20262015
}
20272016

20282017
fn integer_decode_f32(f: f32) -> (u64, i16, i8) {
2029-
// Safety: this identical to the implementation of f32::to_bits(),
2030-
// which is only available starting at Rust 1.20
2031-
let bits: u32 = unsafe { mem::transmute(f) };
2018+
let bits: u32 = f.to_bits();
20322019
let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 };
20332020
let mut exponent: i16 = ((bits >> 23) & 0xff) as i16;
20342021
let mantissa = if exponent == 0 {
@@ -2042,9 +2029,7 @@ fn integer_decode_f32(f: f32) -> (u64, i16, i8) {
20422029
}
20432030

20442031
fn integer_decode_f64(f: f64) -> (u64, i16, i8) {
2045-
// Safety: this identical to the implementation of f64::to_bits(),
2046-
// which is only available starting at Rust 1.20
2047-
let bits: u64 = unsafe { mem::transmute(f) };
2032+
let bits: u64 = f.to_bits();
20482033
let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 };
20492034
let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16;
20502035
let mantissa = if exponent == 0 {

tests/cast.rs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,9 @@ macro_rules! float_test_edge {
171171
let small = if $t::MIN == 0 || mem::size_of::<$t>() < mem::size_of::<$f>() {
172172
$t::MIN as $f - 1.0
173173
} else {
174-
($t::MIN as $f).raw_offset(1).floor()
174+
($t::MIN as $f).raw_inc().floor()
175175
};
176-
let fmin = small.raw_offset(-1);
176+
let fmin = small.raw_dec();
177177
dbg!(" testing min {}\n\tvs. {:.0}\n\tand {:.0}", $t::MIN, fmin, small);
178178
assert_eq!(Some($t::MIN), cast::<$f, $t>($t::MIN as $f));
179179
assert_eq!(Some($t::MIN), cast::<$f, $t>(fmin));
@@ -183,11 +183,11 @@ macro_rules! float_test_edge {
183183
($t::MAX, $t::MAX as $f + 1.0)
184184
} else {
185185
let large = $t::MAX as $f; // rounds up!
186-
let max = large.raw_offset(-1) as $t; // the next smallest possible
186+
let max = large.raw_dec() as $t; // the next smallest possible
187187
assert_eq!(max.count_ones(), $f::MANTISSA_DIGITS);
188188
(max, large)
189189
};
190-
let fmax = large.raw_offset(-1);
190+
let fmax = large.raw_dec();
191191
dbg!(" testing max {}\n\tvs. {:.0}\n\tand {:.0}", max, fmax, large);
192192
assert_eq!(Some(max), cast::<$f, $t>(max as $f));
193193
assert_eq!(Some(max), cast::<$f, $t>(fmax));
@@ -201,27 +201,27 @@ macro_rules! float_test_edge {
201201
}
202202

203203
trait RawOffset: Sized {
204-
type Raw;
205-
fn raw_offset(self, offset: Self::Raw) -> Self;
204+
fn raw_inc(self) -> Self;
205+
fn raw_dec(self) -> Self;
206206
}
207207

208208
impl RawOffset for f32 {
209-
type Raw = i32;
210-
fn raw_offset(self, offset: Self::Raw) -> Self {
211-
unsafe {
212-
let raw: Self::Raw = mem::transmute(self);
213-
mem::transmute(raw + offset)
214-
}
209+
fn raw_inc(self) -> Self {
210+
Self::from_bits(self.to_bits() + 1)
211+
}
212+
213+
fn raw_dec(self) -> Self {
214+
Self::from_bits(self.to_bits() - 1)
215215
}
216216
}
217217

218218
impl RawOffset for f64 {
219-
type Raw = i64;
220-
fn raw_offset(self, offset: Self::Raw) -> Self {
221-
unsafe {
222-
let raw: Self::Raw = mem::transmute(self);
223-
mem::transmute(raw + offset)
224-
}
219+
fn raw_inc(self) -> Self {
220+
Self::from_bits(self.to_bits() + 1)
221+
}
222+
223+
fn raw_dec(self) -> Self {
224+
Self::from_bits(self.to_bits() - 1)
225225
}
226226
}
227227

0 commit comments

Comments
 (0)