Skip to content

Commit 35e323a

Browse files
committed
Remove WideInt
1 parent 400c504 commit 35e323a

File tree

5 files changed

+36
-79
lines changed

5 files changed

+36
-79
lines changed

src/float/cmp.rs

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#![allow(unreachable_code)]
22

33
use float::Float;
4-
use int::{CastInto, Int};
4+
use int::Int;
55

66
#[derive(Clone, Copy)]
77
enum Result {
@@ -31,13 +31,7 @@ impl Result {
3131
}
3232
}
3333

34-
fn cmp<F: Float>(a: F, b: F) -> Result
35-
where
36-
u32: CastInto<F::Int>,
37-
F::Int: CastInto<u32>,
38-
i32: CastInto<F::Int>,
39-
F::Int: CastInto<i32>,
40-
{
34+
fn cmp<F: Float>(a: F, b: F) -> Result {
4135
let one = F::Int::ONE;
4236
let zero = F::Int::ZERO;
4337
let szero = F::SignedInt::ZERO;
@@ -90,13 +84,8 @@ where
9084
}
9185
}
9286
}
93-
fn unord<F: Float>(a: F, b: F) -> bool
94-
where
95-
u32: CastInto<F::Int>,
96-
F::Int: CastInto<u32>,
97-
i32: CastInto<F::Int>,
98-
F::Int: CastInto<i32>,
99-
{
87+
88+
fn unord<F: Float>(a: F, b: F) -> bool {
10089
let one = F::Int::ONE;
10190

10291
let sign_bit = F::SIGN_MASK as F::Int;

src/float/div.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use float::Float;
2-
use int::{CastInto, Int, WideInt};
2+
use int::{CastInto, DInt, HInt, Int};
33

44
fn div32<F: Float>(a: F, b: F) -> F
55
where
66
u32: CastInto<F::Int>,
77
F::Int: CastInto<u32>,
88
i32: CastInto<F::Int>,
99
F::Int: CastInto<i32>,
10-
F::Int: WideInt,
10+
F::Int: HInt,
1111
{
1212
let one = F::Int::ONE;
1313
let zero = F::Int::ZERO;
@@ -156,7 +156,7 @@ where
156156
// is the error in the reciprocal of b scaled by the maximum
157157
// possible value of a. As a consequence of this error bound,
158158
// either q or nextafter(q) is the correctly rounded
159-
let (mut quotient, _) = <F::Int as WideInt>::wide_mul(a_significand << 1, reciprocal.cast());
159+
let mut quotient = (a_significand << 1).widen_mul(reciprocal.cast()).hi();
160160

161161
// Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0).
162162
// In either case, we are going to compute a residual of the form
@@ -211,7 +211,7 @@ where
211211
F::Int: CastInto<u64>,
212212
i64: CastInto<F::Int>,
213213
F::Int: CastInto<i64>,
214-
F::Int: WideInt,
214+
F::Int: HInt,
215215
{
216216
let one = F::Int::ONE;
217217
let zero = F::Int::ZERO;
@@ -394,7 +394,7 @@ where
394394

395395
// We need a 64 x 64 multiply high to compute q, which isn't a basic
396396
// operation in C, so we need to be a little bit fussy.
397-
let (mut quotient, _) = <F::Int as WideInt>::wide_mul(a_significand << 2, reciprocal.cast());
397+
let mut quotient = (a_significand << 2).widen_mul(reciprocal.cast()).hi();
398398

399399
// Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0).
400400
// In either case, we are going to compute a residual of the form

src/float/mod.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ pub mod pow;
1313
pub mod sub;
1414

1515
/// Trait for some basic operations on floats
16-
pub(crate) trait Float:
16+
#[doc(hidden)]
17+
pub trait Float:
1718
Copy
1819
+ PartialEq
1920
+ PartialOrd
@@ -66,7 +67,6 @@ pub(crate) trait Float:
6667
/// Returns `self` transmuted to `Self::SignedInt`
6768
fn signed_repr(self) -> Self::SignedInt;
6869

69-
#[cfg(test)]
7070
/// Checks if two floats have the same bit representation. *Except* for NaNs! NaN can be
7171
/// represented in multiple different ways. This method returns `true` if two NaNs are
7272
/// compared.
@@ -80,6 +80,9 @@ pub(crate) trait Float:
8080

8181
/// Returns (normalized exponent, normalized significand)
8282
fn normalize(significand: Self::Int) -> (i32, Self::Int);
83+
84+
/// Returns if `self` is subnormal
85+
fn is_subnormal(&self) -> bool;
8386
}
8487

8588
// FIXME: Some of this can be removed if RFC Issue #1424 is resolved
@@ -106,7 +109,6 @@ macro_rules! float_impl {
106109
fn signed_repr(self) -> Self::SignedInt {
107110
unsafe { mem::transmute(self) }
108111
}
109-
#[cfg(test)]
110112
fn eq_repr(self, rhs: Self) -> bool {
111113
if self.is_nan() && rhs.is_nan() {
112114
true
@@ -133,6 +135,9 @@ macro_rules! float_impl {
133135
significand << shift as Self::Int,
134136
)
135137
}
138+
fn is_subnormal(&self) -> bool {
139+
(self.repr() & Self::EXPONENT_MASK) == Self::Int::ZERO
140+
}
136141
}
137142
};
138143
}

src/float/mul.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use float::Float;
2-
use int::{CastInto, Int, WideInt};
2+
use int::{CastInto, DInt, HInt, Int};
33

44
fn mul<F: Float>(a: F, b: F) -> F
55
where
66
u32: CastInto<F::Int>,
77
F::Int: CastInto<u32>,
88
i32: CastInto<F::Int>,
99
F::Int: CastInto<i32>,
10-
F::Int: WideInt,
10+
F::Int: HInt,
1111
{
1212
let one = F::Int::ONE;
1313
let zero = F::Int::ZERO;
@@ -112,8 +112,9 @@ where
112112
// have (exponentBits + 2) integral digits, all but two of which must be
113113
// zero. Normalizing this result is just a conditional left-shift by one
114114
// and bumping the exponent accordingly.
115-
let (mut product_high, mut product_low) =
116-
<F::Int as WideInt>::wide_mul(a_significand, b_significand << exponent_bits);
115+
let (mut product_low, mut product_high) = a_significand
116+
.widen_mul(b_significand << exponent_bits)
117+
.lo_hi();
117118

118119
let a_exponent_i32: i32 = a_exponent.cast();
119120
let b_exponent_i32: i32 = b_exponent.cast();
@@ -126,7 +127,8 @@ where
126127
if (product_high & implicit_bit) != zero {
127128
product_exponent = product_exponent.wrapping_add(1);
128129
} else {
129-
<F::Int as WideInt>::wide_shift_left(&mut product_high, &mut product_low, 1);
130+
product_high = (product_high << 1) | (product_low >> (bits - 1));
131+
product_low <<= 1;
130132
}
131133

132134
// If we have overflowed the type, return +/- infinity.
@@ -142,17 +144,23 @@ where
142144
// handle this case separately, but we make it a special case to
143145
// simplify the shift logic.
144146
let shift = one.wrapping_sub(product_exponent.cast()).cast();
145-
if shift >= bits as i32 {
147+
if shift >= bits {
146148
return F::from_repr(product_sign);
147149
}
148150

149151
// Otherwise, shift the significand of the result so that the round
150152
// bit is the high bit of productLo.
151-
<F::Int as WideInt>::wide_shift_right_with_sticky(
152-
&mut product_high,
153-
&mut product_low,
154-
shift,
155-
)
153+
if shift < bits {
154+
let sticky = product_low << (bits - shift);
155+
product_low = product_high << (bits - shift) | product_low >> shift | sticky;
156+
product_high >>= shift;
157+
} else if shift < (2 * bits) {
158+
let sticky = product_high << (2 * bits - shift) | product_low;
159+
product_low = product_high >> (shift - bits) | sticky;
160+
product_high = zero;
161+
} else {
162+
product_high = zero;
163+
}
156164
} else {
157165
// Result is normal before rounding; insert the exponent.
158166
product_high &= significand_mask;

src/int/mod.rs

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -408,48 +408,3 @@ cast_into!(u64);
408408
cast_into!(i64);
409409
cast_into!(u128);
410410
cast_into!(i128);
411-
412-
pub(crate) trait WideInt: Int {
413-
type Output: Int;
414-
415-
fn wide_mul(self, other: Self) -> (Self, Self);
416-
fn wide_shift_left(&mut self, low: &mut Self, count: i32);
417-
fn wide_shift_right_with_sticky(&mut self, low: &mut Self, count: i32);
418-
}
419-
420-
macro_rules! impl_wide_int {
421-
($ty:ty, $tywide:ty, $bits:expr) => {
422-
impl WideInt for $ty {
423-
type Output = $ty;
424-
425-
fn wide_mul(self, other: Self) -> (Self, Self) {
426-
let product = (self as $tywide).wrapping_mul(other as $tywide);
427-
((product >> ($bits as $ty)) as $ty, product as $ty)
428-
}
429-
430-
fn wide_shift_left(&mut self, low: &mut Self, count: i32) {
431-
*self = (*self << count) | (*low >> ($bits - count));
432-
*low = *low << count;
433-
}
434-
435-
fn wide_shift_right_with_sticky(&mut self, low: &mut Self, count: i32) {
436-
if count < $bits {
437-
let sticky = *low << ($bits - count);
438-
*low = *self << ($bits - count) | *low >> count | sticky;
439-
*self = *self >> count;
440-
} else if count < 2 * $bits {
441-
let sticky = *self << (2 * $bits - count) | *low;
442-
*low = *self >> (count - $bits) | sticky;
443-
*self = 0;
444-
} else {
445-
let sticky = *self | *low;
446-
*self = sticky;
447-
*self = 0;
448-
}
449-
}
450-
}
451-
};
452-
}
453-
454-
impl_wide_int!(u32, u64, 32);
455-
impl_wide_int!(u64, u128, 64);

0 commit comments

Comments
 (0)