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>