Skip to content

Commit 46cfa05

Browse files
committed
Introduce a float_impl! macro to avoid duplication
1 parent 9bdedec commit 46cfa05

File tree

1 file changed

+39
-67
lines changed

1 file changed

+39
-67
lines changed

src/float/mod.rs

+39-67
Original file line numberDiff line numberDiff line change
@@ -60,73 +60,45 @@ pub trait Float: Sized + Copy {
6060

6161
// FIXME: Some of this can be removed if RFC Issue #1424 is resolved
6262
// https://github.com/rust-lang/rfcs/issues/1424
63-
impl Float for f32 {
64-
type Int = u32;
65-
const BITS: u32 = 32;
66-
const SIGNIFICAND_BITS: u32 = 23;
67-
68-
const SIGN_MASK: Self::Int = 1 << (Self::BITS - 1);
69-
const SIGNIFICAND_MASK: Self::Int = (1 << Self::SIGNIFICAND_BITS) - 1;
70-
const IMPLICIT_BIT: Self::Int = 1 << Self::SIGNIFICAND_BITS;
71-
const EXPONENT_MASK: Self::Int = !(Self::SIGN_MASK | Self::SIGNIFICAND_MASK);
72-
73-
fn repr(self) -> Self::Int {
74-
unsafe { mem::transmute(self) }
75-
}
76-
#[cfg(test)]
77-
fn eq_repr(self, rhs: Self) -> bool {
78-
if self.is_nan() && rhs.is_nan() {
79-
true
80-
} else {
81-
self.repr() == rhs.repr()
82-
}
83-
}
84-
fn from_repr(a: Self::Int) -> Self {
85-
unsafe { mem::transmute(a) }
86-
}
87-
fn from_parts(sign: bool, exponent: Self::Int, significand: Self::Int) -> Self {
88-
Self::from_repr(((sign as Self::Int) << (Self::BITS - 1)) |
89-
((exponent << Self::SIGNIFICAND_BITS) & Self::EXPONENT_MASK) |
90-
(significand & Self::SIGNIFICAND_MASK))
91-
}
92-
fn normalize(significand: Self::Int) -> (i32, Self::Int) {
93-
let shift = significand.leading_zeros()
94-
.wrapping_sub((1u32 << Self::SIGNIFICAND_BITS).leading_zeros());
95-
(1i32.wrapping_sub(shift as i32), significand << shift as Self::Int)
96-
}
97-
}
98-
impl Float for f64 {
99-
type Int = u64;
100-
const BITS: u32 = 64;
101-
const SIGNIFICAND_BITS: u32 = 52;
102-
103-
const SIGN_MASK: Self::Int = 1 << (Self::BITS - 1);
104-
const SIGNIFICAND_MASK: Self::Int = (1 << Self::SIGNIFICAND_BITS) - 1;
105-
const IMPLICIT_BIT: Self::Int = 1 << Self::SIGNIFICAND_BITS;
106-
const EXPONENT_MASK: Self::Int = !(Self::SIGN_MASK | Self::SIGNIFICAND_MASK);
107-
108-
fn repr(self) -> Self::Int {
109-
unsafe { mem::transmute(self) }
110-
}
111-
#[cfg(test)]
112-
fn eq_repr(self, rhs: Self) -> bool {
113-
if self.is_nan() && rhs.is_nan() {
114-
true
115-
} else {
116-
self.repr() == rhs.repr()
63+
macro_rules! float_impl {
64+
($ty:ident, $ity:ident, $bits:expr, $significand_bits:expr) => {
65+
impl Float for $ty {
66+
type Int = $ity;
67+
const BITS: u32 = $bits;
68+
const SIGNIFICAND_BITS: u32 = $significand_bits;
69+
70+
const SIGN_MASK: Self::Int = 1 << (Self::BITS - 1);
71+
const SIGNIFICAND_MASK: Self::Int = (1 << Self::SIGNIFICAND_BITS) - 1;
72+
const IMPLICIT_BIT: Self::Int = 1 << Self::SIGNIFICAND_BITS;
73+
const EXPONENT_MASK: Self::Int = !(Self::SIGN_MASK | Self::SIGNIFICAND_MASK);
74+
75+
fn repr(self) -> Self::Int {
76+
unsafe { mem::transmute(self) }
77+
}
78+
#[cfg(test)]
79+
fn eq_repr(self, rhs: Self) -> bool {
80+
if self.is_nan() && rhs.is_nan() {
81+
true
82+
} else {
83+
self.repr() == rhs.repr()
84+
}
85+
}
86+
fn from_repr(a: Self::Int) -> Self {
87+
unsafe { mem::transmute(a) }
88+
}
89+
fn from_parts(sign: bool, exponent: Self::Int, significand: Self::Int) -> Self {
90+
Self::from_repr(((sign as Self::Int) << (Self::BITS - 1)) |
91+
((exponent << Self::SIGNIFICAND_BITS) & Self::EXPONENT_MASK) |
92+
(significand & Self::SIGNIFICAND_MASK))
93+
}
94+
fn normalize(significand: Self::Int) -> (i32, Self::Int) {
95+
let shift = significand.leading_zeros()
96+
.wrapping_sub((Self::Int::ONE << Self::SIGNIFICAND_BITS).leading_zeros());
97+
(1i32.wrapping_sub(shift as i32), significand << shift as Self::Int)
98+
}
11799
}
118100
}
119-
fn from_repr(a: Self::Int) -> Self {
120-
unsafe { mem::transmute(a) }
121-
}
122-
fn from_parts(sign: bool, exponent: Self::Int, significand: Self::Int) -> Self {
123-
Self::from_repr(((sign as Self::Int) << (Self::BITS - 1)) |
124-
((exponent << Self::SIGNIFICAND_BITS) & Self::EXPONENT_MASK) |
125-
(significand & Self::SIGNIFICAND_MASK))
126-
}
127-
fn normalize(significand: Self::Int) -> (i32, Self::Int) {
128-
let shift = significand.leading_zeros()
129-
.wrapping_sub((1u64 << Self::SIGNIFICAND_BITS).leading_zeros());
130-
(1i32.wrapping_sub(shift as i32), significand << shift as Self::Int)
131-
}
132101
}
102+
103+
float_impl!(f32, u32, 32, 23);
104+
float_impl!(f64, u64, 64, 52);

0 commit comments

Comments
 (0)