Skip to content

Commit a208402

Browse files
committed
Partially revert 482d983
This partially reverts "Convert int_to_float! to a function".
1 parent 789e8c1 commit a208402

File tree

1 file changed

+66
-70
lines changed

1 file changed

+66
-70
lines changed

src/float/conv.rs

Lines changed: 66 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,83 @@
11
use float::Float;
22
use int::{Int, CastInto};
33

4-
fn int_to_float<I: Int, F: Float>(i: I) -> F where
5-
F::Int: CastInto<u32>,
6-
F::Int: CastInto<I>,
7-
I::UnsignedInt: CastInto<F::Int>,
8-
u32: CastInto<F::Int>,
9-
{
10-
if i == I::ZERO {
11-
return F::ZERO;
12-
}
4+
macro_rules! int_to_float {
5+
($i:expr, $ity:ty, $fty:ty) => ({
6+
let i = $i;
7+
if i == 0 {
8+
return 0.0
9+
}
1310

14-
let two = I::UnsignedInt::ONE + I::UnsignedInt::ONE;
15-
let four = two + two;
16-
let mant_dig = F::SIGNIFICAND_BITS + 1;
17-
let exponent_bias = F::EXPONENT_BIAS;
11+
let mant_dig = <$fty>::SIGNIFICAND_BITS + 1;
12+
let exponent_bias = <$fty>::EXPONENT_BIAS;
1813

19-
let n = I::BITS;
20-
let (s, a) = i.extract_sign();
21-
let mut a = a;
14+
let n = <$ity>::BITS;
15+
let (s, a) = i.extract_sign();
16+
let mut a = a;
2217

23-
// number of significant digits
24-
let sd = n - a.leading_zeros();
18+
// number of significant digits
19+
let sd = n - a.leading_zeros();
2520

26-
// exponent
27-
let mut e = sd - 1;
21+
// exponent
22+
let mut e = sd - 1;
2823

29-
if I::BITS < mant_dig {
30-
return F::from_parts(s,
31-
(e + exponent_bias).cast(),
32-
a.cast() << (mant_dig - e - 1));
33-
}
24+
if <$ity>::BITS < mant_dig {
25+
return <$fty>::from_parts(s,
26+
(e + exponent_bias) as <$fty as Float>::Int,
27+
(a as <$fty as Float>::Int) << (mant_dig - e - 1))
28+
}
3429

35-
a = if sd > mant_dig {
36-
/* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
37-
* finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
38-
* 12345678901234567890123456
39-
* 1 = msb 1 bit
40-
* P = bit MANT_DIG-1 bits to the right of 1
41-
* Q = bit MANT_DIG bits to the right of 1
42-
* R = "or" of all bits to the right of Q
43-
*/
44-
let mant_dig_plus_one = mant_dig + 1;
45-
let mant_dig_plus_two = mant_dig + 2;
46-
a = if sd == mant_dig_plus_one {
47-
a << 1
48-
} else if sd == mant_dig_plus_two {
30+
a = if sd > mant_dig {
31+
/* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
32+
* finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
33+
* 12345678901234567890123456
34+
* 1 = msb 1 bit
35+
* P = bit MANT_DIG-1 bits to the right of 1
36+
* Q = bit MANT_DIG bits to the right of 1
37+
* R = "or" of all bits to the right of Q
38+
*/
39+
let mant_dig_plus_one = mant_dig + 1;
40+
let mant_dig_plus_two = mant_dig + 2;
41+
a = if sd == mant_dig_plus_one {
42+
a << 1
43+
} else if sd == mant_dig_plus_two {
44+
a
45+
} else {
46+
(a >> (sd - mant_dig_plus_two)) as <$ity as Int>::UnsignedInt |
47+
((a & <$ity as Int>::UnsignedInt::max_value()).wrapping_shl((n + mant_dig_plus_two) - sd) != 0) as <$ity as Int>::UnsignedInt
48+
};
49+
50+
/* finish: */
51+
a |= ((a & 4) != 0) as <$ity as Int>::UnsignedInt; /* Or P into R */
52+
a += 1; /* round - this step may add a significant bit */
53+
a >>= 2; /* dump Q and R */
54+
55+
/* a is now rounded to mant_dig or mant_dig+1 bits */
56+
if (a & (1 << mant_dig)) != 0 {
57+
a >>= 1; e += 1;
58+
}
4959
a
60+
/* a is now rounded to mant_dig bits */
5061
} else {
51-
(a >> (sd - mant_dig_plus_two)) |
52-
Int::from_bool((a & I::UnsignedInt::max_value()).wrapping_shl((n + mant_dig_plus_two) - sd) != Int::ZERO)
62+
a.wrapping_shl(mant_dig - sd)
63+
/* a is now rounded to mant_dig bits */
5364
};
5465

55-
/* finish: */
56-
a |= Int::from_bool((a & four) != I::UnsignedInt::ZERO); /* Or P into R */
57-
a += Int::ONE; /* round - this step may add a significant bit */
58-
a >>= 2; /* dump Q and R */
59-
60-
/* a is now rounded to mant_dig or mant_dig+1 bits */
61-
if (a & (I::UnsignedInt::ONE << mant_dig)) != Int::ZERO {
62-
a >>= 1; e += 1;
63-
}
64-
a
65-
/* a is now rounded to mant_dig bits */
66-
} else {
67-
a.wrapping_shl(mant_dig - sd)
68-
/* a is now rounded to mant_dig bits */
69-
};
70-
71-
F::from_parts(s,
72-
(e + exponent_bias).cast(),
73-
a.cast())
66+
<$fty>::from_parts(s,
67+
(e + exponent_bias) as <$fty as Float>::Int,
68+
a as <$fty as Float>::Int)
69+
})
7470
}
7571

7672
intrinsics! {
7773
#[arm_aeabi_alias = __aeabi_i2f]
7874
pub extern "C" fn __floatsisf(i: i32) -> f32 {
79-
int_to_float(i)
75+
int_to_float!(i, i32, f32)
8076
}
8177

8278
#[arm_aeabi_alias = __aeabi_i2d]
8379
pub extern "C" fn __floatsidf(i: i32) -> f64 {
84-
int_to_float(i)
80+
int_to_float!(i, i32, f64)
8581
}
8682

8783
#[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))]
@@ -92,46 +88,46 @@ intrinsics! {
9288
if cfg!(target_arch = "x86_64") {
9389
i as f64
9490
} else {
95-
int_to_float(i)
91+
int_to_float!(i, i64, f64)
9692
}
9793
}
9894

9995
#[unadjusted_on_win64]
10096
pub extern "C" fn __floattisf(i: i128) -> f32 {
101-
int_to_float(i)
97+
int_to_float!(i, i128, f32)
10298
}
10399

104100
#[unadjusted_on_win64]
105101
pub extern "C" fn __floattidf(i: i128) -> f64 {
106-
int_to_float(i)
102+
int_to_float!(i, i128, f64)
107103
}
108104

109105
#[arm_aeabi_alias = __aeabi_ui2f]
110106
pub extern "C" fn __floatunsisf(i: u32) -> f32 {
111-
int_to_float(i)
107+
int_to_float!(i, u32, f32)
112108
}
113109

114110
#[arm_aeabi_alias = __aeabi_ui2d]
115111
pub extern "C" fn __floatunsidf(i: u32) -> f64 {
116-
int_to_float(i)
112+
int_to_float!(i, u32, f64)
117113
}
118114

119115
#[use_c_shim_if(all(not(target_env = "msvc"),
120116
any(target_arch = "x86",
121117
all(not(windows), target_arch = "x86_64"))))]
122118
#[arm_aeabi_alias = __aeabi_ul2d]
123119
pub extern "C" fn __floatundidf(i: u64) -> f64 {
124-
int_to_float(i)
120+
int_to_float!(i, u64, f64)
125121
}
126122

127123
#[unadjusted_on_win64]
128124
pub extern "C" fn __floatuntisf(i: u128) -> f32 {
129-
int_to_float(i)
125+
int_to_float!(i, u128, f32)
130126
}
131127

132128
#[unadjusted_on_win64]
133129
pub extern "C" fn __floatuntidf(i: u128) -> f64 {
134-
int_to_float(i)
130+
int_to_float!(i, u128, f64)
135131
}
136132
}
137133

0 commit comments

Comments
 (0)