root / src / lapack / util / dlamch.f @ 2
Historique | Voir | Annoter | Télécharger (23,96 ko)
1 |
DOUBLE PRECISION FUNCTION DLAMCH( CMACH ) |
---|---|
2 |
* |
3 |
* -- LAPACK auxiliary routine (version 3.2) -- |
4 |
* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. |
5 |
* November 2006 |
6 |
* |
7 |
* .. Scalar Arguments .. |
8 |
CHARACTER CMACH |
9 |
* .. |
10 |
* |
11 |
* Purpose |
12 |
* ======= |
13 |
* |
14 |
* DLAMCH determines double precision machine parameters. |
15 |
* |
16 |
* Arguments |
17 |
* ========= |
18 |
* |
19 |
* CMACH (input) CHARACTER*1 |
20 |
* Specifies the value to be returned by DLAMCH: |
21 |
* = 'E' or 'e', DLAMCH := eps |
22 |
* = 'S' or 's , DLAMCH := sfmin |
23 |
* = 'B' or 'b', DLAMCH := base |
24 |
* = 'P' or 'p', DLAMCH := eps*base |
25 |
* = 'N' or 'n', DLAMCH := t |
26 |
* = 'R' or 'r', DLAMCH := rnd |
27 |
* = 'M' or 'm', DLAMCH := emin |
28 |
* = 'U' or 'u', DLAMCH := rmin |
29 |
* = 'L' or 'l', DLAMCH := emax |
30 |
* = 'O' or 'o', DLAMCH := rmax |
31 |
* |
32 |
* where |
33 |
* |
34 |
* eps = relative machine precision |
35 |
* sfmin = safe minimum, such that 1/sfmin does not overflow |
36 |
* base = base of the machine |
37 |
* prec = eps*base |
38 |
* t = number of (base) digits in the mantissa |
39 |
* rnd = 1.0 when rounding occurs in addition, 0.0 otherwise |
40 |
* emin = minimum exponent before (gradual) underflow |
41 |
* rmin = underflow threshold - base**(emin-1) |
42 |
* emax = largest exponent before overflow |
43 |
* rmax = overflow threshold - (base**emax)*(1-eps) |
44 |
* |
45 |
* ===================================================================== |
46 |
* |
47 |
* .. Parameters .. |
48 |
DOUBLE PRECISION ONE, ZERO |
49 |
PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) |
50 |
* .. |
51 |
* .. Local Scalars .. |
52 |
LOGICAL FIRST, LRND |
53 |
INTEGER BETA, IMAX, IMIN, IT |
54 |
DOUBLE PRECISION BASE, EMAX, EMIN, EPS, PREC, RMACH, RMAX, RMIN, |
55 |
$ RND, SFMIN, SMALL, T |
56 |
* .. |
57 |
* .. External Functions .. |
58 |
LOGICAL LSAME |
59 |
EXTERNAL LSAME |
60 |
* .. |
61 |
* .. External Subroutines .. |
62 |
EXTERNAL DLAMC2 |
63 |
* .. |
64 |
* .. Save statement .. |
65 |
SAVE FIRST, EPS, SFMIN, BASE, T, RND, EMIN, RMIN, |
66 |
$ EMAX, RMAX, PREC |
67 |
* .. |
68 |
* .. Data statements .. |
69 |
DATA FIRST / .TRUE. / |
70 |
* .. |
71 |
* .. Executable Statements .. |
72 |
* |
73 |
IF( FIRST ) THEN |
74 |
CALL DLAMC2( BETA, IT, LRND, EPS, IMIN, RMIN, IMAX, RMAX ) |
75 |
BASE = BETA |
76 |
T = IT |
77 |
IF( LRND ) THEN |
78 |
RND = ONE |
79 |
EPS = ( BASE**( 1-IT ) ) / 2 |
80 |
ELSE |
81 |
RND = ZERO |
82 |
EPS = BASE**( 1-IT ) |
83 |
END IF |
84 |
PREC = EPS*BASE |
85 |
EMIN = IMIN |
86 |
EMAX = IMAX |
87 |
SFMIN = RMIN |
88 |
SMALL = ONE / RMAX |
89 |
IF( SMALL.GE.SFMIN ) THEN |
90 |
* |
91 |
* Use SMALL plus a bit, to avoid the possibility of rounding |
92 |
* causing overflow when computing 1/sfmin. |
93 |
* |
94 |
SFMIN = SMALL*( ONE+EPS ) |
95 |
END IF |
96 |
END IF |
97 |
* |
98 |
IF( LSAME( CMACH, 'E' ) ) THEN |
99 |
RMACH = EPS |
100 |
ELSE IF( LSAME( CMACH, 'S' ) ) THEN |
101 |
RMACH = SFMIN |
102 |
ELSE IF( LSAME( CMACH, 'B' ) ) THEN |
103 |
RMACH = BASE |
104 |
ELSE IF( LSAME( CMACH, 'P' ) ) THEN |
105 |
RMACH = PREC |
106 |
ELSE IF( LSAME( CMACH, 'N' ) ) THEN |
107 |
RMACH = T |
108 |
ELSE IF( LSAME( CMACH, 'R' ) ) THEN |
109 |
RMACH = RND |
110 |
ELSE IF( LSAME( CMACH, 'M' ) ) THEN |
111 |
RMACH = EMIN |
112 |
ELSE IF( LSAME( CMACH, 'U' ) ) THEN |
113 |
RMACH = RMIN |
114 |
ELSE IF( LSAME( CMACH, 'L' ) ) THEN |
115 |
RMACH = EMAX |
116 |
ELSE IF( LSAME( CMACH, 'O' ) ) THEN |
117 |
RMACH = RMAX |
118 |
END IF |
119 |
* |
120 |
DLAMCH = RMACH |
121 |
FIRST = .FALSE. |
122 |
RETURN |
123 |
* |
124 |
* End of DLAMCH |
125 |
* |
126 |
END |
127 |
* |
128 |
************************************************************************ |
129 |
* |
130 |
SUBROUTINE DLAMC1( BETA, T, RND, IEEE1 ) |
131 |
* |
132 |
* -- LAPACK auxiliary routine (version 3.2) -- |
133 |
* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. |
134 |
* November 2006 |
135 |
* |
136 |
* .. Scalar Arguments .. |
137 |
LOGICAL IEEE1, RND |
138 |
INTEGER BETA, T |
139 |
* .. |
140 |
* |
141 |
* Purpose |
142 |
* ======= |
143 |
* |
144 |
* DLAMC1 determines the machine parameters given by BETA, T, RND, and |
145 |
* IEEE1. |
146 |
* |
147 |
* Arguments |
148 |
* ========= |
149 |
* |
150 |
* BETA (output) INTEGER |
151 |
* The base of the machine. |
152 |
* |
153 |
* T (output) INTEGER |
154 |
* The number of ( BETA ) digits in the mantissa. |
155 |
* |
156 |
* RND (output) LOGICAL |
157 |
* Specifies whether proper rounding ( RND = .TRUE. ) or |
158 |
* chopping ( RND = .FALSE. ) occurs in addition. This may not |
159 |
* be a reliable guide to the way in which the machine performs |
160 |
* its arithmetic. |
161 |
* |
162 |
* IEEE1 (output) LOGICAL |
163 |
* Specifies whether rounding appears to be done in the IEEE |
164 |
* 'round to nearest' style. |
165 |
* |
166 |
* Further Details |
167 |
* =============== |
168 |
* |
169 |
* The routine is based on the routine ENVRON by Malcolm and |
170 |
* incorporates suggestions by Gentleman and Marovich. See |
171 |
* |
172 |
* Malcolm M. A. (1972) Algorithms to reveal properties of |
173 |
* floating-point arithmetic. Comms. of the ACM, 15, 949-951. |
174 |
* |
175 |
* Gentleman W. M. and Marovich S. B. (1974) More on algorithms |
176 |
* that reveal properties of floating point arithmetic units. |
177 |
* Comms. of the ACM, 17, 276-277. |
178 |
* |
179 |
* ===================================================================== |
180 |
* |
181 |
* .. Local Scalars .. |
182 |
LOGICAL FIRST, LIEEE1, LRND |
183 |
INTEGER LBETA, LT |
184 |
DOUBLE PRECISION A, B, C, F, ONE, QTR, SAVEC, T1, T2 |
185 |
* .. |
186 |
* .. External Functions .. |
187 |
DOUBLE PRECISION DLAMC3 |
188 |
EXTERNAL DLAMC3 |
189 |
* .. |
190 |
* .. Save statement .. |
191 |
SAVE FIRST, LIEEE1, LBETA, LRND, LT |
192 |
* .. |
193 |
* .. Data statements .. |
194 |
DATA FIRST / .TRUE. / |
195 |
* .. |
196 |
* .. Executable Statements .. |
197 |
* |
198 |
IF( FIRST ) THEN |
199 |
ONE = 1 |
200 |
* |
201 |
* LBETA, LIEEE1, LT and LRND are the local values of BETA, |
202 |
* IEEE1, T and RND. |
203 |
* |
204 |
* Throughout this routine we use the function DLAMC3 to ensure |
205 |
* that relevant values are stored and not held in registers, or |
206 |
* are not affected by optimizers. |
207 |
* |
208 |
* Compute a = 2.0**m with the smallest positive integer m such |
209 |
* that |
210 |
* |
211 |
* fl( a + 1.0 ) = a. |
212 |
* |
213 |
A = 1 |
214 |
C = 1 |
215 |
* |
216 |
*+ WHILE( C.EQ.ONE )LOOP |
217 |
10 CONTINUE |
218 |
IF( C.EQ.ONE ) THEN |
219 |
A = 2*A |
220 |
C = DLAMC3( A, ONE ) |
221 |
C = DLAMC3( C, -A ) |
222 |
GO TO 10 |
223 |
END IF |
224 |
*+ END WHILE |
225 |
* |
226 |
* Now compute b = 2.0**m with the smallest positive integer m |
227 |
* such that |
228 |
* |
229 |
* fl( a + b ) .gt. a. |
230 |
* |
231 |
B = 1 |
232 |
C = DLAMC3( A, B ) |
233 |
* |
234 |
*+ WHILE( C.EQ.A )LOOP |
235 |
20 CONTINUE |
236 |
IF( C.EQ.A ) THEN |
237 |
B = 2*B |
238 |
C = DLAMC3( A, B ) |
239 |
GO TO 20 |
240 |
END IF |
241 |
*+ END WHILE |
242 |
* |
243 |
* Now compute the base. a and c are neighbouring floating point |
244 |
* numbers in the interval ( beta**t, beta**( t + 1 ) ) and so |
245 |
* their difference is beta. Adding 0.25 to c is to ensure that it |
246 |
* is truncated to beta and not ( beta - 1 ). |
247 |
* |
248 |
QTR = ONE / 4 |
249 |
SAVEC = C |
250 |
C = DLAMC3( C, -A ) |
251 |
LBETA = C + QTR |
252 |
* |
253 |
* Now determine whether rounding or chopping occurs, by adding a |
254 |
* bit less than beta/2 and a bit more than beta/2 to a. |
255 |
* |
256 |
B = LBETA |
257 |
F = DLAMC3( B / 2, -B / 100 ) |
258 |
C = DLAMC3( F, A ) |
259 |
IF( C.EQ.A ) THEN |
260 |
LRND = .TRUE. |
261 |
ELSE |
262 |
LRND = .FALSE. |
263 |
END IF |
264 |
F = DLAMC3( B / 2, B / 100 ) |
265 |
C = DLAMC3( F, A ) |
266 |
IF( ( LRND ) .AND. ( C.EQ.A ) ) |
267 |
$ LRND = .FALSE. |
268 |
* |
269 |
* Try and decide whether rounding is done in the IEEE 'round to |
270 |
* nearest' style. B/2 is half a unit in the last place of the two |
271 |
* numbers A and SAVEC. Furthermore, A is even, i.e. has last bit |
272 |
* zero, and SAVEC is odd. Thus adding B/2 to A should not change |
273 |
* A, but adding B/2 to SAVEC should change SAVEC. |
274 |
* |
275 |
T1 = DLAMC3( B / 2, A ) |
276 |
T2 = DLAMC3( B / 2, SAVEC ) |
277 |
LIEEE1 = ( T1.EQ.A ) .AND. ( T2.GT.SAVEC ) .AND. LRND |
278 |
* |
279 |
* Now find the mantissa, t. It should be the integer part of |
280 |
* log to the base beta of a, however it is safer to determine t |
281 |
* by powering. So we find t as the smallest positive integer for |
282 |
* which |
283 |
* |
284 |
* fl( beta**t + 1.0 ) = 1.0. |
285 |
* |
286 |
LT = 0 |
287 |
A = 1 |
288 |
C = 1 |
289 |
* |
290 |
*+ WHILE( C.EQ.ONE )LOOP |
291 |
30 CONTINUE |
292 |
IF( C.EQ.ONE ) THEN |
293 |
LT = LT + 1 |
294 |
A = A*LBETA |
295 |
C = DLAMC3( A, ONE ) |
296 |
C = DLAMC3( C, -A ) |
297 |
GO TO 30 |
298 |
END IF |
299 |
*+ END WHILE |
300 |
* |
301 |
END IF |
302 |
* |
303 |
BETA = LBETA |
304 |
T = LT |
305 |
RND = LRND |
306 |
IEEE1 = LIEEE1 |
307 |
FIRST = .FALSE. |
308 |
RETURN |
309 |
* |
310 |
* End of DLAMC1 |
311 |
* |
312 |
END |
313 |
* |
314 |
************************************************************************ |
315 |
* |
316 |
SUBROUTINE DLAMC2( BETA, T, RND, EPS, EMIN, RMIN, EMAX, RMAX ) |
317 |
* |
318 |
* -- LAPACK auxiliary routine (version 3.2) -- |
319 |
* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. |
320 |
* November 2006 |
321 |
* |
322 |
* .. Scalar Arguments .. |
323 |
LOGICAL RND |
324 |
INTEGER BETA, EMAX, EMIN, T |
325 |
DOUBLE PRECISION EPS, RMAX, RMIN |
326 |
* .. |
327 |
* |
328 |
* Purpose |
329 |
* ======= |
330 |
* |
331 |
* DLAMC2 determines the machine parameters specified in its argument |
332 |
* list. |
333 |
* |
334 |
* Arguments |
335 |
* ========= |
336 |
* |
337 |
* BETA (output) INTEGER |
338 |
* The base of the machine. |
339 |
* |
340 |
* T (output) INTEGER |
341 |
* The number of ( BETA ) digits in the mantissa. |
342 |
* |
343 |
* RND (output) LOGICAL |
344 |
* Specifies whether proper rounding ( RND = .TRUE. ) or |
345 |
* chopping ( RND = .FALSE. ) occurs in addition. This may not |
346 |
* be a reliable guide to the way in which the machine performs |
347 |
* its arithmetic. |
348 |
* |
349 |
* EPS (output) DOUBLE PRECISION |
350 |
* The smallest positive number such that |
351 |
* |
352 |
* fl( 1.0 - EPS ) .LT. 1.0, |
353 |
* |
354 |
* where fl denotes the computed value. |
355 |
* |
356 |
* EMIN (output) INTEGER |
357 |
* The minimum exponent before (gradual) underflow occurs. |
358 |
* |
359 |
* RMIN (output) DOUBLE PRECISION |
360 |
* The smallest normalized number for the machine, given by |
361 |
* BASE**( EMIN - 1 ), where BASE is the floating point value |
362 |
* of BETA. |
363 |
* |
364 |
* EMAX (output) INTEGER |
365 |
* The maximum exponent before overflow occurs. |
366 |
* |
367 |
* RMAX (output) DOUBLE PRECISION |
368 |
* The largest positive number for the machine, given by |
369 |
* BASE**EMAX * ( 1 - EPS ), where BASE is the floating point |
370 |
* value of BETA. |
371 |
* |
372 |
* Further Details |
373 |
* =============== |
374 |
* |
375 |
* The computation of EPS is based on a routine PARANOIA by |
376 |
* W. Kahan of the University of California at Berkeley. |
377 |
* |
378 |
* ===================================================================== |
379 |
* |
380 |
* .. Local Scalars .. |
381 |
LOGICAL FIRST, IEEE, IWARN, LIEEE1, LRND |
382 |
INTEGER GNMIN, GPMIN, I, LBETA, LEMAX, LEMIN, LT, |
383 |
$ NGNMIN, NGPMIN |
384 |
DOUBLE PRECISION A, B, C, HALF, LEPS, LRMAX, LRMIN, ONE, RBASE, |
385 |
$ SIXTH, SMALL, THIRD, TWO, ZERO |
386 |
* .. |
387 |
* .. External Functions .. |
388 |
DOUBLE PRECISION DLAMC3 |
389 |
EXTERNAL DLAMC3 |
390 |
* .. |
391 |
* .. External Subroutines .. |
392 |
EXTERNAL DLAMC1, DLAMC4, DLAMC5 |
393 |
* .. |
394 |
* .. Intrinsic Functions .. |
395 |
INTRINSIC ABS, MAX, MIN |
396 |
* .. |
397 |
* .. Save statement .. |
398 |
SAVE FIRST, IWARN, LBETA, LEMAX, LEMIN, LEPS, LRMAX, |
399 |
$ LRMIN, LT |
400 |
* .. |
401 |
* .. Data statements .. |
402 |
DATA FIRST / .TRUE. / , IWARN / .FALSE. / |
403 |
* .. |
404 |
* .. Executable Statements .. |
405 |
* |
406 |
IF( FIRST ) THEN |
407 |
ZERO = 0 |
408 |
ONE = 1 |
409 |
TWO = 2 |
410 |
* |
411 |
* LBETA, LT, LRND, LEPS, LEMIN and LRMIN are the local values of |
412 |
* BETA, T, RND, EPS, EMIN and RMIN. |
413 |
* |
414 |
* Throughout this routine we use the function DLAMC3 to ensure |
415 |
* that relevant values are stored and not held in registers, or |
416 |
* are not affected by optimizers. |
417 |
* |
418 |
* DLAMC1 returns the parameters LBETA, LT, LRND and LIEEE1. |
419 |
* |
420 |
CALL DLAMC1( LBETA, LT, LRND, LIEEE1 ) |
421 |
* |
422 |
* Start to find EPS. |
423 |
* |
424 |
B = LBETA |
425 |
A = B**( -LT ) |
426 |
LEPS = A |
427 |
* |
428 |
* Try some tricks to see whether or not this is the correct EPS. |
429 |
* |
430 |
B = TWO / 3 |
431 |
HALF = ONE / 2 |
432 |
SIXTH = DLAMC3( B, -HALF ) |
433 |
THIRD = DLAMC3( SIXTH, SIXTH ) |
434 |
B = DLAMC3( THIRD, -HALF ) |
435 |
B = DLAMC3( B, SIXTH ) |
436 |
B = ABS( B ) |
437 |
IF( B.LT.LEPS ) |
438 |
$ B = LEPS |
439 |
* |
440 |
LEPS = 1 |
441 |
* |
442 |
*+ WHILE( ( LEPS.GT.B ).AND.( B.GT.ZERO ) )LOOP |
443 |
10 CONTINUE |
444 |
IF( ( LEPS.GT.B ) .AND. ( B.GT.ZERO ) ) THEN |
445 |
LEPS = B |
446 |
C = DLAMC3( HALF*LEPS, ( TWO**5 )*( LEPS**2 ) ) |
447 |
C = DLAMC3( HALF, -C ) |
448 |
B = DLAMC3( HALF, C ) |
449 |
C = DLAMC3( HALF, -B ) |
450 |
B = DLAMC3( HALF, C ) |
451 |
GO TO 10 |
452 |
END IF |
453 |
*+ END WHILE |
454 |
* |
455 |
IF( A.LT.LEPS ) |
456 |
$ LEPS = A |
457 |
* |
458 |
* Computation of EPS complete. |
459 |
* |
460 |
* Now find EMIN. Let A = + or - 1, and + or - (1 + BASE**(-3)). |
461 |
* Keep dividing A by BETA until (gradual) underflow occurs. This |
462 |
* is detected when we cannot recover the previous A. |
463 |
* |
464 |
RBASE = ONE / LBETA |
465 |
SMALL = ONE |
466 |
DO 20 I = 1, 3 |
467 |
SMALL = DLAMC3( SMALL*RBASE, ZERO ) |
468 |
20 CONTINUE |
469 |
A = DLAMC3( ONE, SMALL ) |
470 |
CALL DLAMC4( NGPMIN, ONE, LBETA ) |
471 |
CALL DLAMC4( NGNMIN, -ONE, LBETA ) |
472 |
CALL DLAMC4( GPMIN, A, LBETA ) |
473 |
CALL DLAMC4( GNMIN, -A, LBETA ) |
474 |
IEEE = .FALSE. |
475 |
* |
476 |
IF( ( NGPMIN.EQ.NGNMIN ) .AND. ( GPMIN.EQ.GNMIN ) ) THEN |
477 |
IF( NGPMIN.EQ.GPMIN ) THEN |
478 |
LEMIN = NGPMIN |
479 |
* ( Non twos-complement machines, no gradual underflow; |
480 |
* e.g., VAX ) |
481 |
ELSE IF( ( GPMIN-NGPMIN ).EQ.3 ) THEN |
482 |
LEMIN = NGPMIN - 1 + LT |
483 |
IEEE = .TRUE. |
484 |
* ( Non twos-complement machines, with gradual underflow; |
485 |
* e.g., IEEE standard followers ) |
486 |
ELSE |
487 |
LEMIN = MIN( NGPMIN, GPMIN ) |
488 |
* ( A guess; no known machine ) |
489 |
IWARN = .TRUE. |
490 |
END IF |
491 |
* |
492 |
ELSE IF( ( NGPMIN.EQ.GPMIN ) .AND. ( NGNMIN.EQ.GNMIN ) ) THEN |
493 |
IF( ABS( NGPMIN-NGNMIN ).EQ.1 ) THEN |
494 |
LEMIN = MAX( NGPMIN, NGNMIN ) |
495 |
* ( Twos-complement machines, no gradual underflow; |
496 |
* e.g., CYBER 205 ) |
497 |
ELSE |
498 |
LEMIN = MIN( NGPMIN, NGNMIN ) |
499 |
* ( A guess; no known machine ) |
500 |
IWARN = .TRUE. |
501 |
END IF |
502 |
* |
503 |
ELSE IF( ( ABS( NGPMIN-NGNMIN ).EQ.1 ) .AND. |
504 |
$ ( GPMIN.EQ.GNMIN ) ) THEN |
505 |
IF( ( GPMIN-MIN( NGPMIN, NGNMIN ) ).EQ.3 ) THEN |
506 |
LEMIN = MAX( NGPMIN, NGNMIN ) - 1 + LT |
507 |
* ( Twos-complement machines with gradual underflow; |
508 |
* no known machine ) |
509 |
ELSE |
510 |
LEMIN = MIN( NGPMIN, NGNMIN ) |
511 |
* ( A guess; no known machine ) |
512 |
IWARN = .TRUE. |
513 |
END IF |
514 |
* |
515 |
ELSE |
516 |
LEMIN = MIN( NGPMIN, NGNMIN, GPMIN, GNMIN ) |
517 |
* ( A guess; no known machine ) |
518 |
IWARN = .TRUE. |
519 |
END IF |
520 |
FIRST = .FALSE. |
521 |
*** |
522 |
* Comment out this if block if EMIN is ok |
523 |
IF( IWARN ) THEN |
524 |
FIRST = .TRUE. |
525 |
WRITE( 6, FMT = 9999 )LEMIN |
526 |
END IF |
527 |
*** |
528 |
* |
529 |
* Assume IEEE arithmetic if we found denormalised numbers above, |
530 |
* or if arithmetic seems to round in the IEEE style, determined |
531 |
* in routine DLAMC1. A true IEEE machine should have both things |
532 |
* true; however, faulty machines may have one or the other. |
533 |
* |
534 |
IEEE = IEEE .OR. LIEEE1 |
535 |
* |
536 |
* Compute RMIN by successive division by BETA. We could compute |
537 |
* RMIN as BASE**( EMIN - 1 ), but some machines underflow during |
538 |
* this computation. |
539 |
* |
540 |
LRMIN = 1 |
541 |
DO 30 I = 1, 1 - LEMIN |
542 |
LRMIN = DLAMC3( LRMIN*RBASE, ZERO ) |
543 |
30 CONTINUE |
544 |
* |
545 |
* Finally, call DLAMC5 to compute EMAX and RMAX. |
546 |
* |
547 |
CALL DLAMC5( LBETA, LT, LEMIN, IEEE, LEMAX, LRMAX ) |
548 |
END IF |
549 |
* |
550 |
BETA = LBETA |
551 |
T = LT |
552 |
RND = LRND |
553 |
EPS = LEPS |
554 |
EMIN = LEMIN |
555 |
RMIN = LRMIN |
556 |
EMAX = LEMAX |
557 |
RMAX = LRMAX |
558 |
* |
559 |
RETURN |
560 |
* |
561 |
9999 FORMAT( / / ' WARNING. The value EMIN may be incorrect:-', |
562 |
$ ' EMIN = ', I8, / |
563 |
$ ' If, after inspection, the value EMIN looks', |
564 |
$ ' acceptable please comment out ', |
565 |
$ / ' the IF block as marked within the code of routine', |
566 |
$ ' DLAMC2,', / ' otherwise supply EMIN explicitly.', / ) |
567 |
* |
568 |
* End of DLAMC2 |
569 |
* |
570 |
END |
571 |
* |
572 |
************************************************************************ |
573 |
* |
574 |
DOUBLE PRECISION FUNCTION DLAMC3( A, B ) |
575 |
* |
576 |
* -- LAPACK auxiliary routine (version 3.2) -- |
577 |
* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. |
578 |
* November 2006 |
579 |
* |
580 |
* .. Scalar Arguments .. |
581 |
DOUBLE PRECISION A, B |
582 |
* .. |
583 |
* |
584 |
* Purpose |
585 |
* ======= |
586 |
* |
587 |
* DLAMC3 is intended to force A and B to be stored prior to doing |
588 |
* the addition of A and B , for use in situations where optimizers |
589 |
* might hold one of these in a register. |
590 |
* |
591 |
* Arguments |
592 |
* ========= |
593 |
* |
594 |
* A (input) DOUBLE PRECISION |
595 |
* B (input) DOUBLE PRECISION |
596 |
* The values A and B. |
597 |
* |
598 |
* ===================================================================== |
599 |
* |
600 |
* .. Executable Statements .. |
601 |
* |
602 |
DLAMC3 = A + B |
603 |
* |
604 |
RETURN |
605 |
* |
606 |
* End of DLAMC3 |
607 |
* |
608 |
END |
609 |
* |
610 |
************************************************************************ |
611 |
* |
612 |
SUBROUTINE DLAMC4( EMIN, START, BASE ) |
613 |
* |
614 |
* -- LAPACK auxiliary routine (version 3.2) -- |
615 |
* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. |
616 |
* November 2006 |
617 |
* |
618 |
* .. Scalar Arguments .. |
619 |
INTEGER BASE, EMIN |
620 |
DOUBLE PRECISION START |
621 |
* .. |
622 |
* |
623 |
* Purpose |
624 |
* ======= |
625 |
* |
626 |
* DLAMC4 is a service routine for DLAMC2. |
627 |
* |
628 |
* Arguments |
629 |
* ========= |
630 |
* |
631 |
* EMIN (output) INTEGER |
632 |
* The minimum exponent before (gradual) underflow, computed by |
633 |
* setting A = START and dividing by BASE until the previous A |
634 |
* can not be recovered. |
635 |
* |
636 |
* START (input) DOUBLE PRECISION |
637 |
* The starting point for determining EMIN. |
638 |
* |
639 |
* BASE (input) INTEGER |
640 |
* The base of the machine. |
641 |
* |
642 |
* ===================================================================== |
643 |
* |
644 |
* .. Local Scalars .. |
645 |
INTEGER I |
646 |
DOUBLE PRECISION A, B1, B2, C1, C2, D1, D2, ONE, RBASE, ZERO |
647 |
* .. |
648 |
* .. External Functions .. |
649 |
DOUBLE PRECISION DLAMC3 |
650 |
EXTERNAL DLAMC3 |
651 |
* .. |
652 |
* .. Executable Statements .. |
653 |
* |
654 |
A = START |
655 |
ONE = 1 |
656 |
RBASE = ONE / BASE |
657 |
ZERO = 0 |
658 |
EMIN = 1 |
659 |
B1 = DLAMC3( A*RBASE, ZERO ) |
660 |
C1 = A |
661 |
C2 = A |
662 |
D1 = A |
663 |
D2 = A |
664 |
*+ WHILE( ( C1.EQ.A ).AND.( C2.EQ.A ).AND. |
665 |
* $ ( D1.EQ.A ).AND.( D2.EQ.A ) )LOOP |
666 |
10 CONTINUE |
667 |
IF( ( C1.EQ.A ) .AND. ( C2.EQ.A ) .AND. ( D1.EQ.A ) .AND. |
668 |
$ ( D2.EQ.A ) ) THEN |
669 |
EMIN = EMIN - 1 |
670 |
A = B1 |
671 |
B1 = DLAMC3( A / BASE, ZERO ) |
672 |
C1 = DLAMC3( B1*BASE, ZERO ) |
673 |
D1 = ZERO |
674 |
DO 20 I = 1, BASE |
675 |
D1 = D1 + B1 |
676 |
20 CONTINUE |
677 |
B2 = DLAMC3( A*RBASE, ZERO ) |
678 |
C2 = DLAMC3( B2 / RBASE, ZERO ) |
679 |
D2 = ZERO |
680 |
DO 30 I = 1, BASE |
681 |
D2 = D2 + B2 |
682 |
30 CONTINUE |
683 |
GO TO 10 |
684 |
END IF |
685 |
*+ END WHILE |
686 |
* |
687 |
RETURN |
688 |
* |
689 |
* End of DLAMC4 |
690 |
* |
691 |
END |
692 |
* |
693 |
************************************************************************ |
694 |
* |
695 |
SUBROUTINE DLAMC5( BETA, P, EMIN, IEEE, EMAX, RMAX ) |
696 |
* |
697 |
* -- LAPACK auxiliary routine (version 3.2) -- |
698 |
* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. |
699 |
* November 2006 |
700 |
* |
701 |
* .. Scalar Arguments .. |
702 |
LOGICAL IEEE |
703 |
INTEGER BETA, EMAX, EMIN, P |
704 |
DOUBLE PRECISION RMAX |
705 |
* .. |
706 |
* |
707 |
* Purpose |
708 |
* ======= |
709 |
* |
710 |
* DLAMC5 attempts to compute RMAX, the largest machine floating-point |
711 |
* number, without overflow. It assumes that EMAX + abs(EMIN) sum |
712 |
* approximately to a power of 2. It will fail on machines where this |
713 |
* assumption does not hold, for example, the Cyber 205 (EMIN = -28625, |
714 |
* EMAX = 28718). It will also fail if the value supplied for EMIN is |
715 |
* too large (i.e. too close to zero), probably with overflow. |
716 |
* |
717 |
* Arguments |
718 |
* ========= |
719 |
* |
720 |
* BETA (input) INTEGER |
721 |
* The base of floating-point arithmetic. |
722 |
* |
723 |
* P (input) INTEGER |
724 |
* The number of base BETA digits in the mantissa of a |
725 |
* floating-point value. |
726 |
* |
727 |
* EMIN (input) INTEGER |
728 |
* The minimum exponent before (gradual) underflow. |
729 |
* |
730 |
* IEEE (input) LOGICAL |
731 |
* A logical flag specifying whether or not the arithmetic |
732 |
* system is thought to comply with the IEEE standard. |
733 |
* |
734 |
* EMAX (output) INTEGER |
735 |
* The largest exponent before overflow |
736 |
* |
737 |
* RMAX (output) DOUBLE PRECISION |
738 |
* The largest machine floating-point number. |
739 |
* |
740 |
* ===================================================================== |
741 |
* |
742 |
* .. Parameters .. |
743 |
DOUBLE PRECISION ZERO, ONE |
744 |
PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 ) |
745 |
* .. |
746 |
* .. Local Scalars .. |
747 |
INTEGER EXBITS, EXPSUM, I, LEXP, NBITS, TRY, UEXP |
748 |
DOUBLE PRECISION OLDY, RECBAS, Y, Z |
749 |
* .. |
750 |
* .. External Functions .. |
751 |
DOUBLE PRECISION DLAMC3 |
752 |
EXTERNAL DLAMC3 |
753 |
* .. |
754 |
* .. Intrinsic Functions .. |
755 |
INTRINSIC MOD |
756 |
* .. |
757 |
* .. Executable Statements .. |
758 |
* |
759 |
* First compute LEXP and UEXP, two powers of 2 that bound |
760 |
* abs(EMIN). We then assume that EMAX + abs(EMIN) will sum |
761 |
* approximately to the bound that is closest to abs(EMIN). |
762 |
* (EMAX is the exponent of the required number RMAX). |
763 |
* |
764 |
LEXP = 1 |
765 |
EXBITS = 1 |
766 |
10 CONTINUE |
767 |
TRY = LEXP*2 |
768 |
IF( TRY.LE.( -EMIN ) ) THEN |
769 |
LEXP = TRY |
770 |
EXBITS = EXBITS + 1 |
771 |
GO TO 10 |
772 |
END IF |
773 |
IF( LEXP.EQ.-EMIN ) THEN |
774 |
UEXP = LEXP |
775 |
ELSE |
776 |
UEXP = TRY |
777 |
EXBITS = EXBITS + 1 |
778 |
END IF |
779 |
* |
780 |
* Now -LEXP is less than or equal to EMIN, and -UEXP is greater |
781 |
* than or equal to EMIN. EXBITS is the number of bits needed to |
782 |
* store the exponent. |
783 |
* |
784 |
IF( ( UEXP+EMIN ).GT.( -LEXP-EMIN ) ) THEN |
785 |
EXPSUM = 2*LEXP |
786 |
ELSE |
787 |
EXPSUM = 2*UEXP |
788 |
END IF |
789 |
* |
790 |
* EXPSUM is the exponent range, approximately equal to |
791 |
* EMAX - EMIN + 1 . |
792 |
* |
793 |
EMAX = EXPSUM + EMIN - 1 |
794 |
NBITS = 1 + EXBITS + P |
795 |
* |
796 |
* NBITS is the total number of bits needed to store a |
797 |
* floating-point number. |
798 |
* |
799 |
IF( ( MOD( NBITS, 2 ).EQ.1 ) .AND. ( BETA.EQ.2 ) ) THEN |
800 |
* |
801 |
* Either there are an odd number of bits used to store a |
802 |
* floating-point number, which is unlikely, or some bits are |
803 |
* not used in the representation of numbers, which is possible, |
804 |
* (e.g. Cray machines) or the mantissa has an implicit bit, |
805 |
* (e.g. IEEE machines, Dec Vax machines), which is perhaps the |
806 |
* most likely. We have to assume the last alternative. |
807 |
* If this is true, then we need to reduce EMAX by one because |
808 |
* there must be some way of representing zero in an implicit-bit |
809 |
* system. On machines like Cray, we are reducing EMAX by one |
810 |
* unnecessarily. |
811 |
* |
812 |
EMAX = EMAX - 1 |
813 |
END IF |
814 |
* |
815 |
IF( IEEE ) THEN |
816 |
* |
817 |
* Assume we are on an IEEE machine which reserves one exponent |
818 |
* for infinity and NaN. |
819 |
* |
820 |
EMAX = EMAX - 1 |
821 |
END IF |
822 |
* |
823 |
* Now create RMAX, the largest machine number, which should |
824 |
* be equal to (1.0 - BETA**(-P)) * BETA**EMAX . |
825 |
* |
826 |
* First compute 1.0 - BETA**(-P), being careful that the |
827 |
* result is less than 1.0 . |
828 |
* |
829 |
RECBAS = ONE / BETA |
830 |
Z = BETA - ONE |
831 |
Y = ZERO |
832 |
DO 20 I = 1, P |
833 |
Z = Z*RECBAS |
834 |
IF( Y.LT.ONE ) |
835 |
$ OLDY = Y |
836 |
Y = DLAMC3( Y, Z ) |
837 |
20 CONTINUE |
838 |
IF( Y.GE.ONE ) |
839 |
$ Y = OLDY |
840 |
* |
841 |
* Now multiply by BETA**EMAX to get RMAX. |
842 |
* |
843 |
DO 30 I = 1, EMAX |
844 |
Y = DLAMC3( Y*BETA, ZERO ) |
845 |
30 CONTINUE |
846 |
* |
847 |
RMAX = Y |
848 |
RETURN |
849 |
* |
850 |
* End of DLAMC5 |
851 |
* |
852 |
END |