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
CVSweb interface <joel.bertrand@systella.fr>