1
- use core:: num:: Wrapping ;
2
-
3
1
use int:: Int ;
4
2
use float:: Float ;
5
3
@@ -8,44 +6,44 @@ macro_rules! add {
8
6
( $a: expr, $b: expr, $ty: ty) => ( {
9
7
let a = $a;
10
8
let b = $b;
11
- let one = Wrapping ( <$ty as Float >:: Int :: ONE ) ;
12
- let zero = Wrapping ( <$ty as Float >:: Int :: ZERO ) ;
9
+ let one = <$ty as Float >:: Int :: ONE ;
10
+ let zero = <$ty as Float >:: Int :: ZERO ;
13
11
14
- let bits = Wrapping ( <$ty>:: BITS as <$ty as Float >:: Int ) ;
15
- let significand_bits = Wrapping ( <$ty>:: SIGNIFICAND_BITS as <$ty as Float >:: Int ) ;
16
- let exponent_bits = bits - significand_bits - one ;
17
- let max_exponent = ( one << exponent_bits. 0 as usize ) - one;
12
+ let bits = <$ty>:: BITS as <$ty as Float >:: Int ;
13
+ let significand_bits = <$ty>:: SIGNIFICAND_BITS as <$ty as Float >:: Int ;
14
+ let exponent_bits = <$ty> :: EXPONENT_BITS as <$ty as Float > :: Int ;
15
+ let max_exponent = ( one << exponent_bits as usize ) - one;
18
16
19
- let implicit_bit = one << significand_bits. 0 as usize ;
17
+ let implicit_bit = one << significand_bits as usize ;
20
18
let significand_mask = implicit_bit - one;
21
- let sign_bit = one << ( significand_bits + exponent_bits ) . 0 as usize ;
19
+ let sign_bit = <$ty> :: SIGN_MASK as <$ty as Float > :: Int ;
22
20
let abs_mask = sign_bit - one;
23
21
let exponent_mask = abs_mask ^ significand_mask;
24
22
let inf_rep = exponent_mask;
25
23
let quiet_bit = implicit_bit >> 1 ;
26
24
let qnan_rep = exponent_mask | quiet_bit;
27
25
28
- let mut a_rep = Wrapping ( a. repr( ) ) ;
29
- let mut b_rep = Wrapping ( b. repr( ) ) ;
26
+ let mut a_rep = a. repr( ) ;
27
+ let mut b_rep = b. repr( ) ;
30
28
let a_abs = a_rep & abs_mask;
31
29
let b_abs = b_rep & abs_mask;
32
30
33
31
// Detect if a or b is zero, infinity, or NaN.
34
- if a_abs - one >= inf_rep - one ||
35
- b_abs - one >= inf_rep - one {
32
+ if a_abs. wrapping_sub ( one) >= inf_rep - one ||
33
+ b_abs. wrapping_sub ( one) >= inf_rep - one {
36
34
// NaN + anything = qNaN
37
35
if a_abs > inf_rep {
38
- return <$ty as Float >:: from_repr( ( a_abs | quiet_bit) . 0 ) ;
36
+ return <$ty as Float >:: from_repr( a_abs | quiet_bit) ;
39
37
}
40
38
// anything + NaN = qNaN
41
39
if b_abs > inf_rep {
42
- return <$ty as Float >:: from_repr( ( b_abs | quiet_bit) . 0 ) ;
40
+ return <$ty as Float >:: from_repr( b_abs | quiet_bit) ;
43
41
}
44
42
45
43
if a_abs == inf_rep {
46
44
// +/-infinity + -/+infinity = qNaN
47
- if ( a. repr( ) ^ b. repr( ) ) == sign_bit. 0 {
48
- return <$ty as Float >:: from_repr( qnan_rep. 0 ) ;
45
+ if ( a. repr( ) ^ b. repr( ) ) == sign_bit {
46
+ return <$ty as Float >:: from_repr( qnan_rep) ;
49
47
} else {
50
48
// +/-infinity + anything remaining = +/- infinity
51
49
return a;
@@ -58,17 +56,17 @@ macro_rules! add {
58
56
}
59
57
60
58
// zero + anything = anything
61
- if a_abs. 0 == 0 {
59
+ if a_abs == 0 {
62
60
// but we need to get the sign right for zero + zero
63
- if b_abs. 0 == 0 {
61
+ if b_abs == 0 {
64
62
return <$ty as Float >:: from_repr( a. repr( ) & b. repr( ) ) ;
65
63
} else {
66
64
return b;
67
65
}
68
66
}
69
67
70
68
// anything + zero = anything
71
- if b_abs. 0 == 0 {
69
+ if b_abs == 0 {
72
70
return a;
73
71
}
74
72
}
@@ -82,21 +80,21 @@ macro_rules! add {
82
80
}
83
81
84
82
// Extract the exponent and significand from the (possibly swapped) a and b.
85
- let mut a_exponent = Wrapping ( ( a_rep >> significand_bits. 0 as usize & max_exponent) . 0 as i32 ) ;
86
- let mut b_exponent = Wrapping ( ( b_rep >> significand_bits. 0 as usize & max_exponent) . 0 as i32 ) ;
83
+ let mut a_exponent = ( ( a_rep >> significand_bits) & max_exponent) as i32 ;
84
+ let mut b_exponent = ( ( b_rep >> significand_bits) & max_exponent) as i32 ;
87
85
let mut a_significand = a_rep & significand_mask;
88
86
let mut b_significand = b_rep & significand_mask;
89
87
90
88
// normalize any denormals, and adjust the exponent accordingly.
91
- if a_exponent. 0 == 0 {
92
- let ( exponent, significand) = <$ty>:: normalize( a_significand. 0 ) ;
93
- a_exponent = Wrapping ( exponent) ;
94
- a_significand = Wrapping ( significand) ;
89
+ if a_exponent == 0 {
90
+ let ( exponent, significand) = <$ty>:: normalize( a_significand) ;
91
+ a_exponent = exponent;
92
+ a_significand = significand;
95
93
}
96
- if b_exponent. 0 == 0 {
97
- let ( exponent, significand) = <$ty>:: normalize( b_significand. 0 ) ;
98
- b_exponent = Wrapping ( exponent) ;
99
- b_significand = Wrapping ( significand) ;
94
+ if b_exponent == 0 {
95
+ let ( exponent, significand) = <$ty>:: normalize( b_significand) ;
96
+ b_exponent = exponent;
97
+ b_significand = significand;
100
98
}
101
99
102
100
// The sign of the result is the sign of the larger operand, a. If they
@@ -113,72 +111,72 @@ macro_rules! add {
113
111
114
112
// Shift the significand of b by the difference in exponents, with a sticky
115
113
// bottom bit to get rounding correct.
116
- let align = Wrapping ( ( a_exponent - b_exponent) . 0 as <$ty as Float >:: Int ) ;
117
- if align. 0 != 0 {
114
+ let align = a_exponent. wrapping_sub ( b_exponent) as <$ty as Float >:: Int ;
115
+ if align != 0 {
118
116
if align < bits {
119
- let sticky = ( ( b_significand << ( bits - align) . 0 as usize ) . 0 != 0 ) as <$ty as Float >:: Int ;
120
- b_significand = ( b_significand >> align. 0 as usize ) | Wrapping ( sticky) ;
117
+ let sticky = ( b_significand << ( bits. wrapping_sub ( align) as usize ) != 0 ) as <$ty as Float >:: Int ;
118
+ b_significand = ( b_significand >> align as usize ) | sticky;
121
119
} else {
122
120
b_significand = one; // sticky; b is known to be non-zero.
123
121
}
124
122
}
125
123
if subtraction {
126
- a_significand -= b_significand;
124
+ a_significand = a_significand . wrapping_sub ( b_significand) ;
127
125
// If a == -b, return +zero.
128
- if a_significand. 0 == 0 {
126
+ if a_significand == 0 {
129
127
return <$ty as Float >:: from_repr( 0 ) ;
130
128
}
131
129
132
130
// If partial cancellation occured, we need to left-shift the result
133
131
// and adjust the exponent:
134
132
if a_significand < implicit_bit << 3 {
135
- let shift = a_significand. 0 . leading_zeros( ) as i32
136
- - ( implicit_bit << 3 ) . 0 . leading_zeros( ) as i32 ;
133
+ let shift = a_significand. leading_zeros( ) as i32
134
+ - ( implicit_bit << 3 ) . leading_zeros( ) as i32 ;
137
135
a_significand <<= shift as usize ;
138
- a_exponent -= Wrapping ( shift) ;
136
+ a_exponent -= shift;
139
137
}
140
138
} else /* addition */ {
141
139
a_significand += b_significand;
142
140
143
141
// If the addition carried up, we need to right-shift the result and
144
142
// adjust the exponent:
145
- if ( a_significand & implicit_bit << 4 ) . 0 != 0 {
146
- let sticky = ( ( a_significand & one) . 0 != 0 ) as <$ty as Float >:: Int ;
147
- a_significand = a_significand >> 1 | Wrapping ( sticky) ;
148
- a_exponent += Wrapping ( 1 ) ;
143
+ if a_significand & implicit_bit << 4 != 0 {
144
+ let sticky = ( a_significand & one != 0 ) as <$ty as Float >:: Int ;
145
+ a_significand = a_significand >> 1 | sticky;
146
+ a_exponent += 1 ;
149
147
}
150
148
}
151
149
152
150
// If we have overflowed the type, return +/- infinity:
153
- if a_exponent >= Wrapping ( max_exponent. 0 as i32 ) {
154
- return <$ty>:: from_repr( ( inf_rep | result_sign) . 0 ) ;
151
+ if a_exponent >= max_exponent as i32 {
152
+ return <$ty>:: from_repr( inf_rep | result_sign) ;
155
153
}
156
154
157
- if a_exponent. 0 <= 0 {
155
+ if a_exponent <= 0 {
158
156
// Result is denormal before rounding; the exponent is zero and we
159
157
// need to shift the significand.
160
- let shift = Wrapping ( ( Wrapping ( 1 ) - a_exponent) . 0 as <$ty as Float >:: Int ) ;
161
- let sticky = ( ( a_significand << ( bits - shift) . 0 as usize ) . 0 != 0 ) as <$ty as Float >:: Int ;
162
- a_significand = a_significand >> shift. 0 as usize | Wrapping ( sticky) ;
163
- a_exponent = Wrapping ( 0 ) ;
158
+ let shift = ( 1 - a_exponent) as <$ty as Float >:: Int ;
159
+ let sticky = ( ( a_significand << bits. wrapping_sub ( shift) as usize ) != 0 ) as <$ty as Float >:: Int ;
160
+ a_significand = a_significand >> shift as usize | sticky;
161
+ a_exponent = 0 ;
164
162
}
165
163
166
164
// Low three bits are round, guard, and sticky.
167
- let round_guard_sticky: i32 = ( a_significand. 0 & 0x7 ) as i32 ;
165
+ let round_guard_sticky: i32 = ( a_significand & 0x7 ) as i32 ;
168
166
169
167
// Shift the significand into place, and mask off the implicit bit.
170
168
let mut result = a_significand >> 3 & significand_mask;
171
169
172
170
// Insert the exponent and sign.
173
- result |= Wrapping ( a_exponent. 0 as <$ty as Float >:: Int ) << significand_bits. 0 as usize ;
171
+ result |= ( a_exponent as <$ty as Float >:: Int ) << ( significand_bits as usize ) ;
174
172
result |= result_sign;
175
173
176
174
// Final rounding. The result may overflow to infinity, but that is the
177
175
// correct result in that case.
178
176
if round_guard_sticky > 0x4 { result += one; }
179
177
if round_guard_sticky == 0x4 { result += result & one; }
180
178
181
- <$ty>:: from_repr( result. 0 )
179
+ <$ty>:: from_repr( result)
182
180
} )
183
181
}
184
182
0 commit comments