Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

Commit 339502c

Browse files
mb64alexcrichton
authored andcommitted
Change sqrt to use wrapping operations
1 parent 69ded67 commit 339502c

File tree

1 file changed

+32
-31
lines changed

1 file changed

+32
-31
lines changed

src/math/sqrt.rs

+32-31
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
*/
7878

7979
use core::f64;
80+
use core::num::Wrapping;
8081

8182
const TINY: f64 = 1.0e-300;
8283

@@ -96,29 +97,29 @@ pub fn sqrt(x: f64) -> f64 {
9697
}
9798
}
9899
let mut z: f64;
99-
let sign: u32 = 0x80000000;
100+
let sign: Wrapping<u32> = Wrapping(0x80000000);
100101
let mut ix0: i32;
101102
let mut s0: i32;
102103
let mut q: i32;
103104
let mut m: i32;
104105
let mut t: i32;
105106
let mut i: i32;
106-
let mut r: u32;
107-
let mut t1: u32;
108-
let mut s1: u32;
109-
let mut ix1: u32;
110-
let mut q1: u32;
107+
let mut r: Wrapping<u32>;
108+
let mut t1: Wrapping<u32>;
109+
let mut s1: Wrapping<u32>;
110+
let mut ix1: Wrapping<u32>;
111+
let mut q1: Wrapping<u32>;
111112

112113
ix0 = (x.to_bits() >> 32) as i32;
113-
ix1 = x.to_bits() as u32;
114+
ix1 = Wrapping(x.to_bits() as u32);
114115

115116
/* take care of Inf and NaN */
116117
if (ix0 & 0x7ff00000) == 0x7ff00000 {
117118
return x * x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN */
118119
}
119120
/* take care of zero */
120121
if ix0 <= 0 {
121-
if ((ix0 & !(sign as i32)) | ix1 as i32) == 0 {
122+
if ((ix0 & !(sign.0 as i32)) | ix1.0 as i32) == 0 {
122123
return x; /* sqrt(+-0) = +-0 */
123124
}
124125
if ix0 < 0 {
@@ -131,7 +132,7 @@ pub fn sqrt(x: f64) -> f64 {
131132
/* subnormal x */
132133
while ix0 == 0 {
133134
m -= 21;
134-
ix0 |= (ix1 >> 11) as i32;
135+
ix0 |= (ix1 >> 11).0 as i32;
135136
ix1 <<= 21;
136137
}
137138
i = 0;
@@ -140,46 +141,46 @@ pub fn sqrt(x: f64) -> f64 {
140141
ix0 <<= 1;
141142
}
142143
m -= i - 1;
143-
ix0 |= (ix1 >> (32 - i)) as i32;
144-
ix1 <<= i;
144+
ix0 |= (ix1 >> (32 - i) as usize).0 as i32;
145+
ix1 = ix1 << i as usize;
145146
}
146147
m -= 1023; /* unbias exponent */
147148
ix0 = (ix0 & 0x000fffff) | 0x00100000;
148149
if (m & 1) == 1 {
149150
/* odd m, double x to make it even */
150-
ix0 += ix0 + ((ix1 & sign) >> 31) as i32;
151+
ix0 += ix0 + ((ix1 & sign) >> 31).0 as i32;
151152
ix1 += ix1;
152153
}
153154
m >>= 1; /* m = [m/2] */
154155

155156
/* generate sqrt(x) bit by bit */
156-
ix0 += ix0 + ((ix1 & sign) >> 31) as i32;
157+
ix0 += ix0 + ((ix1 & sign) >> 31).0 as i32;
157158
ix1 += ix1;
158159
q = 0; /* [q,q1] = sqrt(x) */
159-
q1 = 0;
160+
q1 = Wrapping(0);
160161
s0 = 0;
161-
s1 = 0;
162-
r = 0x00200000; /* r = moving bit from right to left */
162+
s1 = Wrapping(0);
163+
r = Wrapping(0x00200000); /* r = moving bit from right to left */
163164

164-
while r != 0 {
165-
t = s0 + r as i32;
165+
while r != Wrapping(0) {
166+
t = s0 + r.0 as i32;
166167
if t <= ix0 {
167-
s0 = t + r as i32;
168+
s0 = t + r.0 as i32;
168169
ix0 -= t;
169-
q += r as i32;
170+
q += r.0 as i32;
170171
}
171-
ix0 += ix0 + ((ix1 & sign) >> 31) as i32;
172+
ix0 += ix0 + ((ix1 & sign) >> 31).0 as i32;
172173
ix1 += ix1;
173174
r >>= 1;
174175
}
175176

176177
r = sign;
177-
while r != 0 {
178+
while r != Wrapping(0) {
178179
t1 = s1 + r;
179180
t = s0;
180181
if t < ix0 || (t == ix0 && t1 <= ix1) {
181182
s1 = t1 + r;
182-
if (t1 & sign) == sign && (s1 & sign) == 0 {
183+
if (t1 & sign) == sign && (s1 & sign) == Wrapping(0) {
183184
s0 += 1;
184185
}
185186
ix0 -= t;
@@ -189,26 +190,26 @@ pub fn sqrt(x: f64) -> f64 {
189190
ix1 -= t1;
190191
q1 += r;
191192
}
192-
ix0 += ix0 + ((ix1 & sign) >> 31) as i32;
193+
ix0 += ix0 + ((ix1 & sign) >> 31).0 as i32;
193194
ix1 += ix1;
194195
r >>= 1;
195196
}
196197

197198
/* use floating add to find out rounding direction */
198-
if (ix0 as u32 | ix1) != 0 {
199+
if (ix0 as u32 | ix1.0) != 0 {
199200
z = 1.0 - TINY; /* raise inexact flag */
200201
if z >= 1.0 {
201202
z = 1.0 + TINY;
202-
if q1 == 0xffffffff {
203-
q1 = 0;
203+
if q1.0 == 0xffffffff {
204+
q1 = Wrapping(0);
204205
q += 1;
205206
} else if z > 1.0 {
206-
if q1 == 0xfffffffe {
207+
if q1.0 == 0xfffffffe {
207208
q += 1;
208209
}
209-
q1 += 2;
210+
q1 += Wrapping(2);
210211
} else {
211-
q1 += q1 & 1;
212+
q1 += q1 & Wrapping(1);
212213
}
213214
}
214215
}
@@ -218,5 +219,5 @@ pub fn sqrt(x: f64) -> f64 {
218219
ix1 |= sign;
219220
}
220221
ix0 += m << 20;
221-
f64::from_bits((ix0 as u64) << 32 | ix1 as u64)
222+
f64::from_bits((ix0 as u64) << 32 | ix1.0 as u64)
222223
}

0 commit comments

Comments
 (0)