Annotation of rpl/lapack/lapack/dlamch.f, revision 1.1
1.1 ! bertrand 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>