Skip to content

Commit 915293c

Browse files
committed
Auto merge of #191 - est31:master, r=alexcrichton
Small refactor to use associated consts Yeey less chars. r? @alexcrichton
2 parents 23f14d3 + 46cfa05 commit 915293c

File tree

9 files changed

+123
-189
lines changed

9 files changed

+123
-189
lines changed

src/float/add.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ macro_rules! add {
1010
let one = Wrapping(1 as <$ty as Float>::Int);
1111
let zero = Wrapping(0 as <$ty as Float>::Int);
1212

13-
let bits = Wrapping(<$ty>::bits() as <$ty as Float>::Int);
14-
let significand_bits = Wrapping(<$ty>::significand_bits() as <$ty as Float>::Int);
13+
let bits = Wrapping(<$ty>::BITS as <$ty as Float>::Int);
14+
let significand_bits = Wrapping(<$ty>::SIGNIFICAND_BITS as <$ty as Float>::Int);
1515
let exponent_bits = bits - significand_bits - one;
1616
let max_exponent = (one << exponent_bits.0 as usize) - one;
1717

src/float/conv.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ macro_rules! int_to_float {
88
return 0.0
99
}
1010

11-
let mant_dig = <$fty>::significand_bits() + 1;
12-
let exponent_bias = <$fty>::exponent_bias();
11+
let mant_dig = <$fty>::SIGNIFICAND_BITS + 1;
12+
let exponent_bias = <$fty>::EXPONENT_BIAS;
1313

14-
let n = <$ity>::bits();
14+
let n = <$ity>::BITS;
1515
let (s, a) = i.extract_sign();
1616
let mut a = a;
1717

@@ -21,7 +21,7 @@ macro_rules! int_to_float {
2121
// exponent
2222
let mut e = sd - 1;
2323

24-
if <$ity>::bits() < mant_dig {
24+
if <$ity>::BITS < mant_dig {
2525
return <$fty>::from_parts(s,
2626
(e + exponent_bias) as <$fty as Float>::Int,
2727
(a as <$fty as Float>::Int) << (mant_dig - e - 1))
@@ -142,12 +142,12 @@ macro_rules! float_to_int {
142142
let f = $f;
143143
let fixint_min = <$ity>::min_value();
144144
let fixint_max = <$ity>::max_value();
145-
let fixint_bits = <$ity>::bits() as usize;
145+
let fixint_bits = <$ity>::BITS as usize;
146146
let fixint_unsigned = fixint_min == 0;
147147

148-
let sign_bit = <$fty>::sign_mask();
149-
let significand_bits = <$fty>::significand_bits() as usize;
150-
let exponent_bias = <$fty>::exponent_bias() as usize;
148+
let sign_bit = <$fty>::SIGN_MASK;
149+
let significand_bits = <$fty>::SIGNIFICAND_BITS as usize;
150+
let exponent_bias = <$fty>::EXPONENT_BIAS as usize;
151151
//let exponent_max = <$fty>::exponent_max() as usize;
152152

153153
// Break a into sign, exponent, significand
@@ -157,7 +157,7 @@ macro_rules! float_to_int {
157157
// this is used to work around -1 not being available for unsigned
158158
let sign = if (a_rep & sign_bit) == 0 { Sign::Positive } else { Sign::Negative };
159159
let mut exponent = (a_abs >> significand_bits) as usize;
160-
let significand = (a_abs & <$fty>::significand_mask()) | <$fty>::implicit_bit();
160+
let significand = (a_abs & <$fty>::SIGNIFICAND_MASK) | <$fty>::IMPLICIT_BIT;
161161

162162
// if < 1 or unsigned & negative
163163
if exponent < exponent_bias ||

src/float/mod.rs

Lines changed: 61 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use core::mem;
22

3+
use super::int::Int;
4+
35
pub mod conv;
46
pub mod add;
57
pub mod pow;
@@ -8,39 +10,34 @@ pub mod sub;
810
/// Trait for some basic operations on floats
911
pub trait Float: Sized + Copy {
1012
/// A uint of the same with as the float
11-
type Int;
13+
type Int: Int;
1214

13-
/// Returns the bitwidth of the float type
14-
fn bits() -> u32;
15+
/// The bitwidth of the float type
16+
const BITS: u32;
1517

16-
/// Returns the bitwidth of the significand
17-
fn significand_bits() -> u32;
18+
/// The bitwidth of the significand
19+
const SIGNIFICAND_BITS: u32;
1820

19-
/// Returns the bitwidth of the exponent
20-
fn exponent_bits() -> u32 {
21-
Self::bits() - Self::significand_bits() - 1
22-
}
23-
/// Returns the maximum value of the exponent
24-
fn exponent_max() -> u32 {
25-
(1 << Self::exponent_bits()) - 1
26-
}
21+
/// The bitwidth of the exponent
22+
const EXPONENT_BITS: u32 = Self::BITS - Self::SIGNIFICAND_BITS - 1;
2723

28-
/// Returns the exponent bias value
29-
fn exponent_bias() -> u32 {
30-
Self::exponent_max() >> 1
31-
}
24+
/// The maximum value of the exponent
25+
const EXPONENT_MAX: u32 = (1 << Self::EXPONENT_BITS) - 1;
3226

33-
/// Returns a mask for the sign bit
34-
fn sign_mask() -> Self::Int;
27+
/// The exponent bias value
28+
const EXPONENT_BIAS: u32 = Self::EXPONENT_MAX >> 1;
3529

36-
/// Returns a mask for the significand
37-
fn significand_mask() -> Self::Int;
30+
/// A mask for the sign bit
31+
const SIGN_MASK: Self::Int;
3832

39-
// Returns the implicit bit of the float format
40-
fn implicit_bit() -> Self::Int;
33+
/// A mask for the significand
34+
const SIGNIFICAND_MASK: Self::Int;
4135

42-
/// Returns a mask for the exponent
43-
fn exponent_mask() -> Self::Int;
36+
// The implicit bit of the float format
37+
const IMPLICIT_BIT: Self::Int;
38+
39+
/// A mask for the exponent
40+
const EXPONENT_MASK: Self::Int;
4441

4542
/// Returns `self` transmuted to `Self::Int`
4643
fn repr(self) -> Self::Int;
@@ -63,94 +60,45 @@ pub trait Float: Sized + Copy {
6360

6461
// FIXME: Some of this can be removed if RFC Issue #1424 is resolved
6562
// https://github.com/rust-lang/rfcs/issues/1424
66-
impl Float for f32 {
67-
type Int = u32;
68-
fn bits() -> u32 {
69-
32
70-
}
71-
fn significand_bits() -> u32 {
72-
23
73-
}
74-
fn implicit_bit() -> Self::Int {
75-
1 << Self::significand_bits()
76-
}
77-
fn sign_mask() -> Self::Int {
78-
1 << (Self::bits() - 1)
79-
}
80-
fn significand_mask() -> Self::Int {
81-
(1 << Self::significand_bits()) - 1
82-
}
83-
fn exponent_mask() -> Self::Int {
84-
!(Self::sign_mask() | Self::significand_mask())
85-
}
86-
fn repr(self) -> Self::Int {
87-
unsafe { mem::transmute(self) }
88-
}
89-
#[cfg(test)]
90-
fn eq_repr(self, rhs: Self) -> bool {
91-
if self.is_nan() && rhs.is_nan() {
92-
true
93-
} else {
94-
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+
}
9599
}
96100
}
97-
fn from_repr(a: Self::Int) -> Self {
98-
unsafe { mem::transmute(a) }
99-
}
100-
fn from_parts(sign: bool, exponent: Self::Int, significand: Self::Int) -> Self {
101-
Self::from_repr(((sign as Self::Int) << (Self::bits() - 1)) |
102-
((exponent << Self::significand_bits()) & Self::exponent_mask()) |
103-
(significand & Self::significand_mask()))
104-
}
105-
fn normalize(significand: Self::Int) -> (i32, Self::Int) {
106-
let shift = significand.leading_zeros()
107-
.wrapping_sub((1u32 << Self::significand_bits()).leading_zeros());
108-
(1i32.wrapping_sub(shift as i32), significand << shift as Self::Int)
109-
}
110-
}
111-
impl Float for f64 {
112-
type Int = u64;
113-
fn bits() -> u32 {
114-
64
115-
}
116-
fn significand_bits() -> u32 {
117-
52
118-
}
119-
// Returns the implicit bit of the float format
120-
fn implicit_bit() -> Self::Int {
121-
1 << Self::significand_bits()
122-
}
123-
fn sign_mask() -> Self::Int {
124-
1 << (Self::bits() - 1)
125-
}
126-
fn significand_mask() -> Self::Int {
127-
(1 << Self::significand_bits()) - 1
128-
}
129-
fn exponent_mask() -> Self::Int {
130-
!(Self::sign_mask() | Self::significand_mask())
131-
}
132-
fn repr(self) -> Self::Int {
133-
unsafe { mem::transmute(self) }
134-
}
135-
#[cfg(test)]
136-
fn eq_repr(self, rhs: Self) -> bool {
137-
if self.is_nan() && rhs.is_nan() {
138-
true
139-
} else {
140-
self.repr() == rhs.repr()
141-
}
142-
}
143-
fn from_repr(a: Self::Int) -> Self {
144-
unsafe { mem::transmute(a) }
145-
}
146-
fn from_parts(sign: bool, exponent: Self::Int, significand: Self::Int) -> Self {
147-
Self::from_repr(((sign as Self::Int) << (Self::bits() - 1)) |
148-
((exponent << Self::significand_bits()) & Self::exponent_mask()) |
149-
(significand & Self::significand_mask()))
150-
}
151-
fn normalize(significand: Self::Int) -> (i32, Self::Int) {
152-
let shift = significand.leading_zeros()
153-
.wrapping_sub((1u64 << Self::significand_bits()).leading_zeros());
154-
(1i32.wrapping_sub(shift as i32), significand << shift as Self::Int)
155-
}
156101
}
102+
103+
float_impl!(f32, u32, 32, 23);
104+
float_impl!(f64, u64, 64, 52);

src/float/sub.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ use float::Float;
33
intrinsics! {
44
#[arm_aeabi_alias = __aeabi_fsub]
55
pub extern "C" fn __subsf3(a: f32, b: f32) -> f32 {
6-
a + f32::from_repr(b.repr() ^ f32::sign_mask())
6+
a + f32::from_repr(b.repr() ^ f32::SIGN_MASK)
77
}
88

99
#[arm_aeabi_alias = __aeabi_dsub]
1010
pub extern "C" fn __subdf3(a: f64, b: f64) -> f64 {
11-
a + f64::from_repr(b.repr() ^ f64::sign_mask())
11+
a + f64::from_repr(b.repr() ^ f64::SIGN_MASK)
1212
}
1313
}

src/int/mod.rs

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ pub trait Int:
3939
/// Unsigned version of Self
4040
type UnsignedInt: Int;
4141

42-
/// Returns the bitwidth of the int type
43-
fn bits() -> u32;
42+
/// The bitwidth of the int type
43+
const BITS: u32;
4444

45-
fn zero() -> Self;
46-
fn one() -> Self;
45+
const ZERO: Self;
46+
const ONE: Self;
4747

4848
/// Extracts the sign from self and returns a tuple.
4949
///
@@ -83,17 +83,10 @@ macro_rules! int_impl {
8383
type OtherSign = $ity;
8484
type UnsignedInt = $uty;
8585

86-
fn zero() -> Self {
87-
0
88-
}
89-
90-
fn one() -> Self {
91-
1
92-
}
86+
const BITS: u32 = $bits;
9387

94-
fn bits() -> u32 {
95-
$bits
96-
}
88+
const ZERO: Self = 0;
89+
const ONE: Self = 1;
9790

9891
fn extract_sign(self) -> (bool, $uty) {
9992
(false, self)
@@ -140,17 +133,10 @@ macro_rules! int_impl {
140133
type OtherSign = $uty;
141134
type UnsignedInt = $uty;
142135

143-
fn bits() -> u32 {
144-
$bits
145-
}
146-
147-
fn zero() -> Self {
148-
0
149-
}
136+
const BITS: u32 = $bits;
150137

151-
fn one() -> Self {
152-
1
153-
}
138+
const ZERO: Self = 0;
139+
const ONE: Self = 1;
154140

155141
fn extract_sign(self) -> (bool, $uty) {
156142
if self < 0 {

src/int/mul.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use int::Int;
55

66
trait Mul: LargeInt {
77
fn mul(self, other: Self) -> Self {
8-
let half_bits = Self::bits() / 4;
9-
let lower_mask = !<<Self as LargeInt>::LowHalf>::zero() >> half_bits;
8+
let half_bits = Self::BITS / 4;
9+
let lower_mask = !<<Self as LargeInt>::LowHalf>::ZERO >> half_bits;
1010
let mut low = (self.low() & lower_mask).wrapping_mul(other.low() & lower_mask);
1111
let mut t = low >> half_bits;
1212
low &= lower_mask;
@@ -33,23 +33,23 @@ trait Mulo: Int + ops::Neg<Output = Self> {
3333
*overflow = 0;
3434
let result = self.wrapping_mul(other);
3535
if self == Self::min_value() {
36-
if other != Self::zero() && other != Self::one() {
36+
if other != Self::ZERO && other != Self::ONE {
3737
*overflow = 1;
3838
}
3939
return result;
4040
}
4141
if other == Self::min_value() {
42-
if self != Self::zero() && self != Self::one() {
42+
if self != Self::ZERO && self != Self::ONE {
4343
*overflow = 1;
4444
}
4545
return result;
4646
}
4747

48-
let sa = self >> (Self::bits() - 1);
48+
let sa = self >> (Self::BITS - 1);
4949
let abs_a = (self ^ sa) - sa;
50-
let sb = other >> (Self::bits() - 1);
50+
let sb = other >> (Self::BITS - 1);
5151
let abs_b = (other ^ sb) - sb;
52-
let two = Self::one() + Self::one();
52+
let two = Self::ONE + Self::ONE;
5353
if abs_a < two || abs_b < two {
5454
return result;
5555
}

src/int/sdiv.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ use int::Int;
33
trait Div: Int {
44
/// Returns `a / b`
55
fn div(self, other: Self) -> Self {
6-
let s_a = self >> (Self::bits() - 1);
7-
let s_b = other >> (Self::bits() - 1);
8-
// NOTE it's OK to overflow here because of the `as $uty` cast below
6+
let s_a = self >> (Self::BITS - 1);
7+
let s_b = other >> (Self::BITS - 1);
8+
// NOTE it's OK to overflow here because of the `.unsigned()` below.
99
// This whole operation is computing the absolute value of the inputs
1010
// So some overflow will happen when dealing with e.g. `i64::MIN`
1111
// where the absolute value is `(-i64::MIN) as u64`
@@ -25,10 +25,10 @@ impl Div for i128 {}
2525
trait Mod: Int {
2626
/// Returns `a % b`
2727
fn mod_(self, other: Self) -> Self {
28-
let s = other >> (Self::bits() - 1);
28+
let s = other >> (Self::BITS - 1);
2929
// NOTE(wrapping_sub) see comment in the `div`
3030
let b = (other ^ s).wrapping_sub(s);
31-
let s = self >> (Self::bits() - 1);
31+
let s = self >> (Self::BITS - 1);
3232
let a = (self ^ s).wrapping_sub(s);
3333

3434
let r = a.unsigned().aborting_rem(b.unsigned());

0 commit comments

Comments
 (0)