source: trunk/src/gcc/libjava/java/lang/e_sqrt.c@ 2293

Last change on this file since 2293 was 2, checked in by bird, 23 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 14.0 KB
Line 
1
2/* @(#)e_sqrt.c 5.1 93/09/24 */
3/*
4 * ====================================================
5 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
6 *
7 * Developed at SunPro, a Sun Microsystems, Inc. business.
8 * Permission to use, copy, modify, and distribute this
9 * software is freely granted, provided that this notice
10 * is preserved.
11 * ====================================================
12 */
13
14/* __ieee754_sqrt(x)
15 * Return correctly rounded sqrt.
16 * ------------------------------------------
17 * | Use the hardware sqrt if you have one |
18 * ------------------------------------------
19 * Method:
20 * Bit by bit method using integer arithmetic. (Slow, but portable)
21 * 1. Normalization
22 * Scale x to y in [1,4) with even powers of 2:
23 * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
24 * sqrt(x) = 2^k * sqrt(y)
25 * 2. Bit by bit computation
26 * Let q = sqrt(y) truncated to i bit after binary point (q = 1),
27 * i 0
28 * i+1 2
29 * s = 2*q , and y = 2 * ( y - q ). (1)
30 * i i i i
31 *
32 * To compute q from q , one checks whether
33 * i+1 i
34 *
35 * -(i+1) 2
36 * (q + 2 ) <= y. (2)
37 * i
38 * -(i+1)
39 * If (2) is false, then q = q ; otherwise q = q + 2 .
40 * i+1 i i+1 i
41 *
42 * With some algebric manipulation, it is not difficult to see
43 * that (2) is equivalent to
44 * -(i+1)
45 * s + 2 <= y (3)
46 * i i
47 *
48 * The advantage of (3) is that s and y can be computed by
49 * i i
50 * the following recurrence formula:
51 * if (3) is false
52 *
53 * s = s , y = y ; (4)
54 * i+1 i i+1 i
55 *
56 * otherwise,
57 * -i -(i+1)
58 * s = s + 2 , y = y - s - 2 (5)
59 * i+1 i i+1 i i
60 *
61 * One may easily use induction to prove (4) and (5).
62 * Note. Since the left hand side of (3) contain only i+2 bits,
63 * it does not necessary to do a full (53-bit) comparison
64 * in (3).
65 * 3. Final rounding
66 * After generating the 53 bits result, we compute one more bit.
67 * Together with the remainder, we can decide whether the
68 * result is exact, bigger than 1/2ulp, or less than 1/2ulp
69 * (it will never equal to 1/2ulp).
70 * The rounding mode can be detected by checking whether
71 * huge + tiny is equal to huge, and whether huge - tiny is
72 * equal to huge for some floating point number "huge" and "tiny".
73 *
74 * Special cases:
75 * sqrt(+-0) = +-0 ... exact
76 * sqrt(inf) = inf
77 * sqrt(-ve) = NaN ... with invalid signal
78 * sqrt(NaN) = NaN ... with invalid signal for signaling NaN
79 *
80 * Other methods : see the appended file at the end of the program below.
81 *---------------
82 */
83
84#include "fdlibm.h"
85
86#ifndef _DOUBLE_IS_32BITS
87
88#ifdef __STDC__
89static const double one = 1.0, tiny=1.0e-300;
90#else
91static double one = 1.0, tiny=1.0e-300;
92#endif
93
94#ifdef __STDC__
95 double __ieee754_sqrt(double x)
96#else
97 double __ieee754_sqrt(x)
98 double x;
99#endif
100{
101 double z;
102 int32_t sign = (int)0x80000000;
103 uint32_t r,t1,s1,ix1,q1;
104 int32_t ix0,s0,q,m,t,i;
105
106 EXTRACT_WORDS(ix0,ix1,x);
107
108 /* take care of Inf and NaN */
109 if((ix0&0x7ff00000)==0x7ff00000) {
110 return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
111 sqrt(-inf)=sNaN */
112 }
113 /* take care of zero */
114 if(ix0<=0) {
115 if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */
116 else if(ix0<0)
117 return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
118 }
119 /* normalize x */
120 m = (ix0>>20);
121 if(m==0) { /* subnormal x */
122 while(ix0==0) {
123 m -= 21;
124 ix0 |= (ix1>>11); ix1 <<= 21;
125 }
126 for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1;
127 m -= i-1;
128 ix0 |= (ix1>>(32-i));
129 ix1 <<= i;
130 }
131 m -= 1023; /* unbias exponent */
132 ix0 = (ix0&0x000fffff)|0x00100000;
133 if(m&1){ /* odd m, double x to make it even */
134 ix0 += ix0 + ((ix1&sign)>>31);
135 ix1 += ix1;
136 }
137 m >>= 1; /* m = [m/2] */
138
139 /* generate sqrt(x) bit by bit */
140 ix0 += ix0 + ((ix1&sign)>>31);
141 ix1 += ix1;
142 q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */
143 r = 0x00200000; /* r = moving bit from right to left */
144
145 while(r!=0) {
146 t = s0+r;
147 if(t<=ix0) {
148 s0 = t+r;
149 ix0 -= t;
150 q += r;
151 }
152 ix0 += ix0 + ((ix1&sign)>>31);
153 ix1 += ix1;
154 r>>=1;
155 }
156
157 r = sign;
158 while(r!=0) {
159 t1 = s1+r;
160 t = s0;
161 if((t<ix0)||((t==ix0)&&(t1<=ix1))) {
162 s1 = t1+r;
163 if(((t1&sign)==(uint32_t)sign)&&(s1&sign)==0) s0 += 1;
164 ix0 -= t;
165 if (ix1 < t1) ix0 -= 1;
166 ix1 -= t1;
167 q1 += r;
168 }
169 ix0 += ix0 + ((ix1&sign)>>31);
170 ix1 += ix1;
171 r>>=1;
172 }
173
174 /* use floating add to find out rounding direction */
175 if((ix0|ix1)!=0) {
176 z = one-tiny; /* trigger inexact flag */
177 if (z>=one) {
178 z = one+tiny;
179 if (q1==(uint32_t)0xffffffff) { q1=0; q += 1;}
180 else if (z>one) {
181 if (q1==(uint32_t)0xfffffffe) q+=1;
182 q1+=2;
183 } else
184 q1 += (q1&1);
185 }
186 }
187 ix0 = (q>>1)+0x3fe00000;
188 ix1 = q1>>1;
189 if ((q&1)==1) ix1 |= sign;
190 ix0 += (m <<20);
191 INSERT_WORDS(z,ix0,ix1);
192 return z;
193}
194
195#endif /* defined(_DOUBLE_IS_32BITS) */
196
197/*
198Other methods (use floating-point arithmetic)
199-------------
200(This is a copy of a drafted paper by Prof W. Kahan
201and K.C. Ng, written in May, 1986)
202
203 Two algorithms are given here to implement sqrt(x)
204 (IEEE double precision arithmetic) in software.
205 Both supply sqrt(x) correctly rounded. The first algorithm (in
206 Section A) uses newton iterations and involves four divisions.
207 The second one uses reciproot iterations to avoid division, but
208 requires more multiplications. Both algorithms need the ability
209 to chop results of arithmetic operations instead of round them,
210 and the INEXACT flag to indicate when an arithmetic operation
211 is executed exactly with no roundoff error, all part of the
212 standard (IEEE 754-1985). The ability to perform shift, add,
213 subtract and logical AND operations upon 32-bit words is needed
214 too, though not part of the standard.
215
216A. sqrt(x) by Newton Iteration
217
218 (1) Initial approximation
219
220 Let x0 and x1 be the leading and the trailing 32-bit words of
221 a floating point number x (in IEEE double format) respectively
222
223 1 11 52 ...widths
224 ------------------------------------------------------
225 x: |s| e | f |
226 ------------------------------------------------------
227 msb lsb msb lsb ...order
228
229
230 ------------------------ ------------------------
231 x0: |s| e | f1 | x1: | f2 |
232 ------------------------ ------------------------
233
234 By performing shifts and subtracts on x0 and x1 (both regarded
235 as integers), we obtain an 8-bit approximation of sqrt(x) as
236 follows.
237
238 k := (x0>>1) + 0x1ff80000;
239 y0 := k - T1[31&(k>>15)]. ... y ~ sqrt(x) to 8 bits
240 Here k is a 32-bit integer and T1[] is an integer array containing
241 correction terms. Now magically the floating value of y (y's
242 leading 32-bit word is y0, the value of its trailing word is 0)
243 approximates sqrt(x) to almost 8-bit.