LAPACK  3.4.0
LAPACK: Linear Algebra PACKage
dlamchf77.f
Go to the documentation of this file.
00001 *> \brief \b DLAMCHF77 deprecated
00002 *
00003 *  =========== DOCUMENTATION ===========
00004 *
00005 * Online html documentation available at 
00006 *            http://www.netlib.org/lapack/explore-html/ 
00007 *
00008 *  Definition:
00009 *  ===========
00010 *
00011 *      DOUBLE PRECISION FUNCTION DLAMCH( CMACH )
00012 *  
00013 *
00014 *> \par Purpose:
00015 *  =============
00016 *>
00017 *> \verbatim
00018 *>
00019 *> DLAMCHF77 determines double precision machine parameters.
00020 *> \endverbatim
00021 *
00022 *  Arguments:
00023 *  ==========
00024 *
00025 *> \param[in] CMACH
00026 *> \verbatim
00027 *>          Specifies the value to be returned by DLAMCH:
00028 *>          = 'E' or 'e',   DLAMCH := eps
00029 *>          = 'S' or 's ,   DLAMCH := sfmin
00030 *>          = 'B' or 'b',   DLAMCH := base
00031 *>          = 'P' or 'p',   DLAMCH := eps*base
00032 *>          = 'N' or 'n',   DLAMCH := t
00033 *>          = 'R' or 'r',   DLAMCH := rnd
00034 *>          = 'M' or 'm',   DLAMCH := emin
00035 *>          = 'U' or 'u',   DLAMCH := rmin
00036 *>          = 'L' or 'l',   DLAMCH := emax
00037 *>          = 'O' or 'o',   DLAMCH := rmax
00038 *>          where
00039 *>          eps   = relative machine precision
00040 *>          sfmin = safe minimum, such that 1/sfmin does not overflow
00041 *>          base  = base of the machine
00042 *>          prec  = eps*base
00043 *>          t     = number of (base) digits in the mantissa
00044 *>          rnd   = 1.0 when rounding occurs in addition, 0.0 otherwise
00045 *>          emin  = minimum exponent before (gradual) underflow
00046 *>          rmin  = underflow threshold - base**(emin-1)
00047 *>          emax  = largest exponent before overflow
00048 *>          rmax  = overflow threshold  - (base**emax)*(1-eps)
00049 *> \endverbatim
00050 *
00051 *  Authors:
00052 *  ========
00053 *
00054 *> \author Univ. of Tennessee 
00055 *> \author Univ. of California Berkeley 
00056 *> \author Univ. of Colorado Denver 
00057 *> \author NAG Ltd. 
00058 *
00059 *> \date November 2011
00060 *
00061 *> \ingroup auxOTHERauxiliary
00062 *
00063 *  =====================================================================
00064       DOUBLE PRECISION FUNCTION DLAMCH( CMACH )
00065 *
00066 *  -- LAPACK auxiliary routine (version 3.4.0) --
00067 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00068 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00069 *     November 2011
00070 *
00071 *     .. Scalar Arguments ..
00072       CHARACTER          CMACH
00073 *     ..
00074 *
00075 *     .. Scalar Arguments ..
00076       LOGICAL            IEEE1, RND
00077       INTEGER            BETA, T
00078 *     ..
00079 *
00080 *     .. Scalar Arguments ..
00081       LOGICAL            RND
00082       INTEGER            BETA, EMAX, EMIN, T
00083       DOUBLE PRECISION   EPS, RMAX, RMIN
00084 *     ..
00085 *
00086 *     .. Scalar Arguments ..
00087       DOUBLE PRECISION   A, B
00088 *     ..
00089 *
00090 *     .. Scalar Arguments ..
00091       INTEGER            BASE, EMIN
00092       DOUBLE PRECISION   START
00093 *     ..
00094 *
00095 *     .. Scalar Arguments ..
00096       LOGICAL            IEEE
00097       INTEGER            BETA, EMAX, EMIN, P
00098       DOUBLE PRECISION   RMAX
00099 *     ..
00100 *
00101 * =====================================================================
00102 *
00103 *     .. Parameters ..
00104       DOUBLE PRECISION   ONE, ZERO
00105       PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
00106 *     ..
00107 *     .. Local Scalars ..
00108       LOGICAL            FIRST, LRND
00109       INTEGER            BETA, IMAX, IMIN, IT
00110       DOUBLE PRECISION   BASE, EMAX, EMIN, EPS, PREC, RMACH, RMAX, RMIN,
00111      $                   RND, SFMIN, SMALL, T
00112 *     ..
00113 *     .. External Functions ..
00114       LOGICAL            LSAME
00115       EXTERNAL           LSAME
00116 *     ..
00117 *     .. External Subroutines ..
00118       EXTERNAL           DLAMC2
00119 *     ..
00120 *     .. Save statement ..
00121       SAVE               FIRST, EPS, SFMIN, BASE, T, RND, EMIN, RMIN,
00122      $                   EMAX, RMAX, PREC
00123 *     ..
00124 *     .. Data statements ..
00125       DATA               FIRST / .TRUE. /
00126 *     ..
00127 *     .. Executable Statements ..
00128 *
00129       IF( FIRST ) THEN
00130          CALL DLAMC2( BETA, IT, LRND, EPS, IMIN, RMIN, IMAX, RMAX )
00131          BASE = BETA
00132          T = IT
00133          IF( LRND ) THEN
00134             RND = ONE
00135             EPS = ( BASE**( 1-IT ) ) / 2
00136          ELSE
00137             RND = ZERO
00138             EPS = BASE**( 1-IT )
00139          END IF
00140          PREC = EPS*BASE
00141          EMIN = IMIN
00142          EMAX = IMAX
00143          SFMIN = RMIN
00144          SMALL = ONE / RMAX
00145          IF( SMALL.GE.SFMIN ) THEN
00146 *
00147 *           Use SMALL plus a bit, to avoid the possibility of rounding
00148 *           causing overflow when computing  1/sfmin.
00149 *
00150             SFMIN = SMALL*( ONE+EPS )
00151          END IF
00152       END IF
00153 *
00154       IF( LSAME( CMACH, 'E' ) ) THEN
00155          RMACH = EPS
00156       ELSE IF( LSAME( CMACH, 'S' ) ) THEN
00157          RMACH = SFMIN
00158       ELSE IF( LSAME( CMACH, 'B' ) ) THEN
00159          RMACH = BASE
00160       ELSE IF( LSAME( CMACH, 'P' ) ) THEN
00161          RMACH = PREC
00162       ELSE IF( LSAME( CMACH, 'N' ) ) THEN
00163          RMACH = T
00164       ELSE IF( LSAME( CMACH, 'R' ) ) THEN
00165          RMACH = RND
00166       ELSE IF( LSAME( CMACH, 'M' ) ) THEN
00167          RMACH = EMIN
00168       ELSE IF( LSAME( CMACH, 'U' ) ) THEN
00169          RMACH = RMIN
00170       ELSE IF( LSAME( CMACH, 'L' ) ) THEN
00171          RMACH = EMAX
00172       ELSE IF( LSAME( CMACH, 'O' ) ) THEN
00173          RMACH = RMAX
00174       END IF
00175 *
00176       DLAMCH = RMACH
00177       FIRST  = .FALSE.
00178       RETURN
00179 *
00180 *     End of DLAMCH
00181 *
00182       END
00183 *
00184 ************************************************************************
00185 *
00186 *> \brief \b DLAMC1
00187 *> \details
00188 *> \b Purpose:
00189 *> \verbatim
00190 *> DLAMC1 determines the machine parameters given by BETA, T, RND, and
00191 *> IEEE1.
00192 *> \endverbatim
00193 *>
00194 *> \param[out] BETA
00195 *> \verbatim
00196 *>          The base of the machine.
00197 *> \endverbatim
00198 *>
00199 *> \param[out] T
00200 *> \verbatim
00201 *>          The number of ( BETA ) digits in the mantissa.
00202 *> \endverbatim
00203 *>
00204 *> \param[out] RND
00205 *> \verbatim
00206 *>          Specifies whether proper rounding  ( RND = .TRUE. )  or
00207 *>          chopping  ( RND = .FALSE. )  occurs in addition. This may not
00208 *>          be a reliable guide to the way in which the machine performs
00209 *>          its arithmetic.
00210 *> \endverbatim
00211 *>
00212 *> \param[out] IEEE1
00213 *> \verbatim
00214 *>          Specifies whether rounding appears to be done in the IEEE
00215 *>          'round to nearest' style.
00216 *> \endverbatim
00217 *> \author LAPACK is a software package provided by Univ. of Tennessee, Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..
00218 *> \date November 2011
00219 *> \ingroup auxOTHERauxiliary
00220 *>
00221 *> \details \b Further \b Details
00222 *> \verbatim
00223 *>
00224 *>  The routine is based on the routine  ENVRON  by Malcolm and
00225 *>  incorporates suggestions by Gentleman and Marovich. See
00226 *>
00227 *>     Malcolm M. A. (1972) Algorithms to reveal properties of
00228 *>        floating-point arithmetic. Comms. of the ACM, 15, 949-951.
00229 *>
00230 *>     Gentleman W. M. and Marovich S. B. (1974) More on algorithms
00231 *>        that reveal properties of floating point arithmetic units.
00232 *>        Comms. of the ACM, 17, 276-277.
00233 *> \endverbatim
00234 *>
00235       SUBROUTINE DLAMC1( BETA, T, RND, IEEE1 )
00236 *
00237 *  -- LAPACK auxiliary routine (version 3.4.0) --
00238 *     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
00239 *     November 2010
00240 *
00241 *     .. Scalar Arguments ..
00242       LOGICAL            IEEE1, RND
00243       INTEGER            BETA, T
00244 *     ..
00245 * =====================================================================
00246 *
00247 *     .. Local Scalars ..
00248       LOGICAL            FIRST, LIEEE1, LRND
00249       INTEGER            LBETA, LT
00250       DOUBLE PRECISION   A, B, C, F, ONE, QTR, SAVEC, T1, T2
00251 *     ..
00252 *     .. External Functions ..
00253       DOUBLE PRECISION   DLAMC3
00254       EXTERNAL           DLAMC3
00255 *     ..
00256 *     .. Save statement ..
00257       SAVE               FIRST, LIEEE1, LBETA, LRND, LT
00258 *     ..
00259 *     .. Data statements ..
00260       DATA               FIRST / .TRUE. /
00261 *     ..
00262 *     .. Executable Statements ..
00263 *
00264       IF( FIRST ) THEN
00265          ONE = 1
00266 *
00267 *        LBETA,  LIEEE1,  LT and  LRND  are the  local values  of  BETA,
00268 *        IEEE1, T and RND.
00269 *
00270 *        Throughout this routine  we use the function  DLAMC3  to ensure
00271 *        that relevant values are  stored and not held in registers,  or
00272 *        are not affected by optimizers.
00273 *
00274 *        Compute  a = 2.0**m  with the  smallest positive integer m such
00275 *        that
00276 *
00277 *           fl( a + 1.0 ) = a.
00278 *
00279          A = 1
00280          C = 1
00281 *
00282 *+       WHILE( C.EQ.ONE )LOOP
00283    10    CONTINUE
00284          IF( C.EQ.ONE ) THEN
00285             A = 2*A
00286             C = DLAMC3( A, ONE )
00287             C = DLAMC3( C, -A )
00288             GO TO 10
00289          END IF
00290 *+       END WHILE
00291 *
00292 *        Now compute  b = 2.0**m  with the smallest positive integer m
00293 *        such that
00294 *
00295 *           fl( a + b ) .gt. a.
00296 *
00297          B = 1
00298          C = DLAMC3( A, B )
00299 *
00300 *+       WHILE( C.EQ.A )LOOP
00301    20    CONTINUE
00302          IF( C.EQ.A ) THEN
00303             B = 2*B
00304             C = DLAMC3( A, B )
00305             GO TO 20
00306          END IF
00307 *+       END WHILE
00308 *
00309 *        Now compute the base.  a and c  are neighbouring floating point
00310 *        numbers  in the  interval  ( beta**t, beta**( t + 1 ) )  and so
00311 *        their difference is beta. Adding 0.25 to c is to ensure that it
00312 *        is truncated to beta and not ( beta - 1 ).
00313 *
00314          QTR = ONE / 4
00315          SAVEC = C
00316          C = DLAMC3( C, -A )
00317          LBETA = C + QTR
00318 *
00319 *        Now determine whether rounding or chopping occurs,  by adding a
00320 *        bit  less  than  beta/2  and a  bit  more  than  beta/2  to  a.
00321 *
00322          B = LBETA
00323          F = DLAMC3( B / 2, -B / 100 )
00324          C = DLAMC3( F, A )
00325          IF( C.EQ.A ) THEN
00326             LRND = .TRUE.
00327          ELSE
00328             LRND = .FALSE.
00329          END IF
00330          F = DLAMC3( B / 2, B / 100 )
00331          C = DLAMC3( F, A )
00332          IF( ( LRND ) .AND. ( C.EQ.A ) )
00333      $      LRND = .FALSE.
00334 *
00335 *        Try and decide whether rounding is done in the  IEEE  'round to
00336 *        nearest' style. B/2 is half a unit in the last place of the two
00337 *        numbers A and SAVEC. Furthermore, A is even, i.e. has last  bit
00338 *        zero, and SAVEC is odd. Thus adding B/2 to A should not  change
00339 *        A, but adding B/2 to SAVEC should change SAVEC.
00340 *
00341          T1 = DLAMC3( B / 2, A )
00342          T2 = DLAMC3( B / 2, SAVEC )
00343          LIEEE1 = ( T1.EQ.A ) .AND. ( T2.GT.SAVEC ) .AND. LRND
00344 *
00345 *        Now find  the  mantissa, t.  It should  be the  integer part of
00346 *        log to the base beta of a,  however it is safer to determine  t
00347 *        by powering.  So we find t as the smallest positive integer for
00348 *        which
00349 *
00350 *           fl( beta**t + 1.0 ) = 1.0.
00351 *
00352          LT = 0
00353          A = 1
00354          C = 1
00355 *
00356 *+       WHILE( C.EQ.ONE )LOOP
00357    30    CONTINUE
00358          IF( C.EQ.ONE ) THEN
00359             LT = LT + 1
00360             A = A*LBETA
00361             C = DLAMC3( A, ONE )
00362             C = DLAMC3( C, -A )
00363             GO TO 30
00364          END IF
00365 *+       END WHILE
00366 *
00367       END IF
00368 *
00369       BETA = LBETA
00370       T = LT
00371       RND = LRND
00372       IEEE1 = LIEEE1
00373       FIRST = .FALSE.
00374       RETURN
00375 *
00376 *     End of DLAMC1
00377 *
00378       END
00379 *
00380 ************************************************************************
00381 *
00382 *> \brief \b DLAMC2
00383 *> \details
00384 *> \b Purpose:
00385 *> \verbatim
00386 *> DLAMC2 determines the machine parameters specified in its argument
00387 *> list.
00388 *> \endverbatim
00389 *> \author LAPACK is a software package provided by Univ. of Tennessee, Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..
00390 *> \date November 2011
00391 *> \ingroup auxOTHERauxiliary
00392 *>
00393 *> \param[out] BETA
00394 *> \verbatim
00395 *>          The base of the machine.
00396 *> \endverbatim
00397 *>
00398 *> \param[out] T
00399 *> \verbatim
00400 *>          The number of ( BETA ) digits in the mantissa.
00401 *> \endverbatim
00402 *>
00403 *> \param[out] RND
00404 *> \verbatim
00405 *>          Specifies whether proper rounding  ( RND = .TRUE. )  or
00406 *>          chopping  ( RND = .FALSE. )  occurs in addition. This may not
00407 *>          be a reliable guide to the way in which the machine performs
00408 *>          its arithmetic.
00409 *> \endverbatim
00410 *>
00411 *> \param[out] EPS
00412 *> \verbatim
00413 *>          The smallest positive number such that
00414 *>             fl( 1.0 - EPS ) .LT. 1.0,
00415 *>          where fl denotes the computed value.
00416 *> \endverbatim
00417 *>
00418 *> \param[out] EMIN
00419 *> \verbatim
00420 *>          The minimum exponent before (gradual) underflow occurs.
00421 *> \endverbatim
00422 *>
00423 *> \param[out] RMIN
00424 *> \verbatim
00425 *>          The smallest normalized number for the machine, given by
00426 *>          BASE**( EMIN - 1 ), where  BASE  is the floating point value
00427 *>          of BETA.
00428 *> \endverbatim
00429 *>
00430 *> \param[out] EMAX
00431 *> \verbatim
00432 *>          The maximum exponent before overflow occurs.
00433 *> \endverbatim
00434 *>
00435 *> \param[out] RMAX
00436 *> \verbatim
00437 *>          The largest positive number for the machine, given by
00438 *>          BASE**EMAX * ( 1 - EPS ), where  BASE  is the floating point
00439 *>          value of BETA.
00440 *> \endverbatim
00441 *>
00442 *> \details \b Further \b Details
00443 *> \verbatim
00444 *>
00445 *>  The computation of  EPS  is based on a routine PARANOIA by
00446 *>  W. Kahan of the University of California at Berkeley.
00447 *> \endverbatim
00448       SUBROUTINE DLAMC2( BETA, T, RND, EPS, EMIN, RMIN, EMAX, RMAX )
00449 *
00450 *  -- LAPACK auxiliary routine (version 3.4.0) --
00451 *     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
00452 *     November 2010
00453 *
00454 *     .. Scalar Arguments ..
00455       LOGICAL            RND
00456       INTEGER            BETA, EMAX, EMIN, T
00457       DOUBLE PRECISION   EPS, RMAX, RMIN
00458 *     ..
00459 * =====================================================================
00460 *
00461 *     .. Local Scalars ..
00462       LOGICAL            FIRST, IEEE, IWARN, LIEEE1, LRND
00463       INTEGER            GNMIN, GPMIN, I, LBETA, LEMAX, LEMIN, LT,
00464      $                   NGNMIN, NGPMIN
00465       DOUBLE PRECISION   A, B, C, HALF, LEPS, LRMAX, LRMIN, ONE, RBASE,
00466      $                   SIXTH, SMALL, THIRD, TWO, ZERO
00467 *     ..
00468 *     .. External Functions ..
00469       DOUBLE PRECISION   DLAMC3
00470       EXTERNAL           DLAMC3
00471 *     ..
00472 *     .. External Subroutines ..
00473       EXTERNAL           DLAMC1, DLAMC4, DLAMC5
00474 *     ..
00475 *     .. Intrinsic Functions ..
00476       INTRINSIC          ABS, MAX, MIN
00477 *     ..
00478 *     .. Save statement ..
00479       SAVE               FIRST, IWARN, LBETA, LEMAX, LEMIN, LEPS, LRMAX,
00480      $                   LRMIN, LT
00481 *     ..
00482 *     .. Data statements ..
00483       DATA               FIRST / .TRUE. / , IWARN / .FALSE. /
00484 *     ..
00485 *     .. Executable Statements ..
00486 *
00487       IF( FIRST ) THEN
00488          ZERO = 0
00489          ONE = 1
00490          TWO = 2
00491 *
00492 *        LBETA, LT, LRND, LEPS, LEMIN and LRMIN  are the local values of
00493 *        BETA, T, RND, EPS, EMIN and RMIN.
00494 *
00495 *        Throughout this routine  we use the function  DLAMC3  to ensure
00496 *        that relevant values are stored  and not held in registers,  or
00497 *        are not affected by optimizers.
00498 *
00499 *        DLAMC1 returns the parameters  LBETA, LT, LRND and LIEEE1.
00500 *
00501          CALL DLAMC1( LBETA, LT, LRND, LIEEE1 )
00502 *
00503 *        Start to find EPS.
00504 *
00505          B = LBETA
00506          A = B**( -LT )
00507          LEPS = A
00508 *
00509 *        Try some tricks to see whether or not this is the correct  EPS.
00510 *
00511          B = TWO / 3
00512          HALF = ONE / 2
00513          SIXTH = DLAMC3( B, -HALF )
00514          THIRD = DLAMC3( SIXTH, SIXTH )
00515          B = DLAMC3( THIRD, -HALF )
00516          B = DLAMC3( B, SIXTH )
00517          B = ABS( B )
00518          IF( B.LT.LEPS )
00519      $      B = LEPS
00520 *
00521          LEPS = 1
00522 *
00523 *+       WHILE( ( LEPS.GT.B ).AND.( B.GT.ZERO ) )LOOP
00524    10    CONTINUE
00525          IF( ( LEPS.GT.B ) .AND. ( B.GT.ZERO ) ) THEN
00526             LEPS = B
00527             C = DLAMC3( HALF*LEPS, ( TWO**5 )*( LEPS**2 ) )
00528             C = DLAMC3( HALF, -C )
00529             B = DLAMC3( HALF, C )
00530             C = DLAMC3( HALF, -B )
00531             B = DLAMC3( HALF, C )
00532             GO TO 10
00533          END IF
00534 *+       END WHILE
00535 *
00536          IF( A.LT.LEPS )
00537      $      LEPS = A
00538 *
00539 *        Computation of EPS complete.
00540 *
00541 *        Now find  EMIN.  Let A = + or - 1, and + or - (1 + BASE**(-3)).
00542 *        Keep dividing  A by BETA until (gradual) underflow occurs. This
00543 *        is detected when we cannot recover the previous A.
00544 *
00545          RBASE = ONE / LBETA
00546          SMALL = ONE
00547          DO 20 I = 1, 3
00548             SMALL = DLAMC3( SMALL*RBASE, ZERO )
00549    20    CONTINUE
00550          A = DLAMC3( ONE, SMALL )
00551          CALL DLAMC4( NGPMIN, ONE, LBETA )
00552          CALL DLAMC4( NGNMIN, -ONE, LBETA )
00553          CALL DLAMC4( GPMIN, A, LBETA )
00554          CALL DLAMC4( GNMIN, -A, LBETA )
00555          IEEE = .FALSE.
00556 *
00557          IF( ( NGPMIN.EQ.NGNMIN ) .AND. ( GPMIN.EQ.GNMIN ) ) THEN
00558             IF( NGPMIN.EQ.GPMIN ) THEN
00559                LEMIN = NGPMIN
00560 *            ( Non twos-complement machines, no gradual underflow;
00561 *              e.g.,  VAX )
00562             ELSE IF( ( GPMIN-NGPMIN ).EQ.3 ) THEN
00563                LEMIN = NGPMIN - 1 + LT
00564                IEEE = .TRUE.
00565 *            ( Non twos-complement machines, with gradual underflow;
00566 *              e.g., IEEE standard followers )
00567             ELSE
00568                LEMIN = MIN( NGPMIN, GPMIN )
00569 *            ( A guess; no known machine )
00570                IWARN = .TRUE.
00571             END IF
00572 *
00573          ELSE IF( ( NGPMIN.EQ.GPMIN ) .AND. ( NGNMIN.EQ.GNMIN ) ) THEN
00574             IF( ABS( NGPMIN-NGNMIN ).EQ.1 ) THEN
00575                LEMIN = MAX( NGPMIN, NGNMIN )
00576 *            ( Twos-complement machines, no gradual underflow;
00577 *              e.g., CYBER 205 )
00578             ELSE
00579                LEMIN = MIN( NGPMIN, NGNMIN )
00580 *            ( A guess; no known machine )
00581                IWARN = .TRUE.
00582             END IF
00583 *
00584          ELSE IF( ( ABS( NGPMIN-NGNMIN ).EQ.1 ) .AND.
00585      $            ( GPMIN.EQ.GNMIN ) ) THEN
00586             IF( ( GPMIN-MIN( NGPMIN, NGNMIN ) ).EQ.3 ) THEN
00587                LEMIN = MAX( NGPMIN, NGNMIN ) - 1 + LT
00588 *            ( Twos-complement machines with gradual underflow;
00589 *              no known machine )
00590             ELSE
00591                LEMIN = MIN( NGPMIN, NGNMIN )
00592 *            ( A guess; no known machine )
00593                IWARN = .TRUE.
00594             END IF
00595 *
00596          ELSE
00597             LEMIN = MIN( NGPMIN, NGNMIN, GPMIN, GNMIN )
00598 *         ( A guess; no known machine )
00599             IWARN = .TRUE.
00600          END IF
00601          FIRST = .FALSE.
00602 ***
00603 * Comment out this if block if EMIN is ok
00604          IF( IWARN ) THEN
00605             FIRST = .TRUE.
00606             WRITE( 6, FMT = 9999 )LEMIN
00607          END IF
00608 ***
00609 *
00610 *        Assume IEEE arithmetic if we found denormalised  numbers above,
00611 *        or if arithmetic seems to round in the  IEEE style,  determined
00612 *        in routine DLAMC1. A true IEEE machine should have both  things
00613 *        true; however, faulty machines may have one or the other.
00614 *
00615          IEEE = IEEE .OR. LIEEE1
00616 *
00617 *        Compute  RMIN by successive division by  BETA. We could compute
00618 *        RMIN as BASE**( EMIN - 1 ),  but some machines underflow during
00619 *        this computation.
00620 *
00621          LRMIN = 1
00622          DO 30 I = 1, 1 - LEMIN
00623             LRMIN = DLAMC3( LRMIN*RBASE, ZERO )
00624    30    CONTINUE
00625 *
00626 *        Finally, call DLAMC5 to compute EMAX and RMAX.
00627 *
00628          CALL DLAMC5( LBETA, LT, LEMIN, IEEE, LEMAX, LRMAX )
00629       END IF
00630 *
00631       BETA = LBETA
00632       T = LT
00633       RND = LRND
00634       EPS = LEPS
00635       EMIN = LEMIN
00636       RMIN = LRMIN
00637       EMAX = LEMAX
00638       RMAX = LRMAX
00639 *
00640       RETURN
00641 *
00642  9999 FORMAT( / / ' WARNING. The value EMIN may be incorrect:-',
00643      $      '  EMIN = ', I8, /
00644      $      ' If, after inspection, the value EMIN looks',
00645      $      ' acceptable please comment out ',
00646      $      / ' the IF block as marked within the code of routine',
00647      $      ' DLAMC2,', / ' otherwise supply EMIN explicitly.', / )
00648 *
00649 *     End of DLAMC2
00650 *
00651       END
00652 *
00653 ************************************************************************
00654 *
00655 *> \brief \b DLAMC3
00656 *> \details
00657 *> \b Purpose:
00658 *> \verbatim
00659 *> DLAMC3  is intended to force  A  and  B  to be stored prior to doing
00660 *> the addition of  A  and  B ,  for use in situations where optimizers
00661 *> might hold one of these in a register.
00662 *> \endverbatim
00663 *>
00664 *> \param[in] A
00665 *>
00666 *> \param[in] B
00667 *> \verbatim
00668 *>          The values A and B.
00669 *> \endverbatim
00670 
00671       DOUBLE PRECISION FUNCTION DLAMC3( A, B )
00672 *
00673 *  -- LAPACK auxiliary routine (version 3.4.0) --
00674 *     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
00675 *     November 2010
00676 *
00677 *     .. Scalar Arguments ..
00678       DOUBLE PRECISION   A, B
00679 *     ..
00680 * =====================================================================
00681 *
00682 *     .. Executable Statements ..
00683 *
00684       DLAMC3 = A + B
00685 *
00686       RETURN
00687 *
00688 *     End of DLAMC3
00689 *
00690       END
00691 *
00692 ************************************************************************
00693 *
00694 *> \brief \b DLAMC4
00695 *> \details
00696 *> \b Purpose:
00697 *> \verbatim
00698 *> DLAMC4 is a service routine for DLAMC2.
00699 *> \endverbatim
00700 *>
00701 *> \param[out] EMIN
00702 *> \verbatim
00703 *>          The minimum exponent before (gradual) underflow, computed by
00704 *>          setting A = START and dividing by BASE until the previous A
00705 *>          can not be recovered.
00706 *> \endverbatim
00707 *>
00708 *> \param[in] START
00709 *> \verbatim
00710 *>          The starting point for determining EMIN.
00711 *> \endverbatim
00712 *>
00713 *> \param[in] BASE
00714 *> \verbatim
00715 *>          The base of the machine.
00716 *> \endverbatim
00717 *>
00718       SUBROUTINE DLAMC4( EMIN, START, BASE )
00719 *
00720 *  -- LAPACK auxiliary routine (version 3.4.0) --
00721 *     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
00722 *     November 2010
00723 *
00724 *     .. Scalar Arguments ..
00725       INTEGER            BASE, EMIN
00726       DOUBLE PRECISION   START
00727 *     ..
00728 * =====================================================================
00729 *
00730 *     .. Local Scalars ..
00731       INTEGER            I
00732       DOUBLE PRECISION   A, B1, B2, C1, C2, D1, D2, ONE, RBASE, ZERO
00733 *     ..
00734 *     .. External Functions ..
00735       DOUBLE PRECISION   DLAMC3
00736       EXTERNAL           DLAMC3
00737 *     ..
00738 *     .. Executable Statements ..
00739 *
00740       A = START
00741       ONE = 1
00742       RBASE = ONE / BASE
00743       ZERO = 0
00744       EMIN = 1
00745       B1 = DLAMC3( A*RBASE, ZERO )
00746       C1 = A
00747       C2 = A
00748       D1 = A
00749       D2 = A
00750 *+    WHILE( ( C1.EQ.A ).AND.( C2.EQ.A ).AND.
00751 *    $       ( D1.EQ.A ).AND.( D2.EQ.A )      )LOOP
00752    10 CONTINUE
00753       IF( ( C1.EQ.A ) .AND. ( C2.EQ.A ) .AND. ( D1.EQ.A ) .AND.
00754      $    ( D2.EQ.A ) ) THEN
00755          EMIN = EMIN - 1
00756          A = B1
00757          B1 = DLAMC3( A / BASE, ZERO )
00758          C1 = DLAMC3( B1*BASE, ZERO )
00759          D1 = ZERO
00760          DO 20 I = 1, BASE
00761             D1 = D1 + B1
00762    20    CONTINUE
00763          B2 = DLAMC3( A*RBASE, ZERO )
00764          C2 = DLAMC3( B2 / RBASE, ZERO )
00765          D2 = ZERO
00766          DO 30 I = 1, BASE
00767             D2 = D2 + B2
00768    30    CONTINUE
00769          GO TO 10
00770       END IF
00771 *+    END WHILE
00772 *
00773       RETURN
00774 *
00775 *     End of DLAMC4
00776 *
00777       END
00778 *
00779 ************************************************************************
00780 *
00781 *> \brief \b DLAMC5
00782 *> \details
00783 *> \b Purpose:
00784 *> \verbatim
00785 *> DLAMC5 attempts to compute RMAX, the largest machine floating-point
00786 *> number, without overflow.  It assumes that EMAX + abs(EMIN) sum
00787 *> approximately to a power of 2.  It will fail on machines where this
00788 *> assumption does not hold, for example, the Cyber 205 (EMIN = -28625,
00789 *> EMAX = 28718).  It will also fail if the value supplied for EMIN is
00790 *> too large (i.e. too close to zero), probably with overflow.
00791 *> \endverbatim
00792 *>
00793 *> \param[in] BETA
00794 *> \verbatim
00795 *>          The base of floating-point arithmetic.
00796 *> \endverbatim
00797 *>
00798 *> \param[in] P
00799 *> \verbatim
00800 *>          The number of base BETA digits in the mantissa of a
00801 *>          floating-point value.
00802 *> \endverbatim
00803 *>
00804 *> \param[in] EMIN
00805 *> \verbatim
00806 *>          The minimum exponent before (gradual) underflow.
00807 *> \endverbatim
00808 *>
00809 *> \param[in] IEEE
00810 *> \verbatim
00811 *>          A logical flag specifying whether or not the arithmetic
00812 *>          system is thought to comply with the IEEE standard.
00813 *> \endverbatim
00814 *>
00815 *> \param[out] EMAX
00816 *> \verbatim
00817 *>          The largest exponent before overflow
00818 *> \endverbatim
00819 *>
00820 *> \param[out] RMAX
00821 *> \verbatim
00822 *>          The largest machine floating-point number.
00823 *> \endverbatim
00824 *>
00825       SUBROUTINE DLAMC5( BETA, P, EMIN, IEEE, EMAX, RMAX )
00826 *
00827 *  -- LAPACK auxiliary routine (version 3.4.0) --
00828 *     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
00829 *     November 2010
00830 *
00831 *     .. Scalar Arguments ..
00832       LOGICAL            IEEE
00833       INTEGER            BETA, EMAX, EMIN, P
00834       DOUBLE PRECISION   RMAX
00835 *     ..
00836 * =====================================================================
00837 *
00838 *     .. Parameters ..
00839       DOUBLE PRECISION   ZERO, ONE
00840       PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
00841 *     ..
00842 *     .. Local Scalars ..
00843       INTEGER            EXBITS, EXPSUM, I, LEXP, NBITS, TRY, UEXP
00844       DOUBLE PRECISION   OLDY, RECBAS, Y, Z
00845 *     ..
00846 *     .. External Functions ..
00847       DOUBLE PRECISION   DLAMC3
00848       EXTERNAL           DLAMC3
00849 *     ..
00850 *     .. Intrinsic Functions ..
00851       INTRINSIC          MOD
00852 *     ..
00853 *     .. Executable Statements ..
00854 *
00855 *     First compute LEXP and UEXP, two powers of 2 that bound
00856 *     abs(EMIN). We then assume that EMAX + abs(EMIN) will sum
00857 *     approximately to the bound that is closest to abs(EMIN).
00858 *     (EMAX is the exponent of the required number RMAX).
00859 *
00860       LEXP = 1
00861       EXBITS = 1
00862    10 CONTINUE
00863       TRY = LEXP*2
00864       IF( TRY.LE.( -EMIN ) ) THEN
00865          LEXP = TRY
00866          EXBITS = EXBITS + 1
00867          GO TO 10
00868       END IF
00869       IF( LEXP.EQ.-EMIN ) THEN
00870          UEXP = LEXP
00871       ELSE
00872          UEXP = TRY
00873          EXBITS = EXBITS + 1
00874       END IF
00875 *
00876 *     Now -LEXP is less than or equal to EMIN, and -UEXP is greater
00877 *     than or equal to EMIN. EXBITS is the number of bits needed to
00878 *     store the exponent.
00879 *
00880       IF( ( UEXP+EMIN ).GT.( -LEXP-EMIN ) ) THEN
00881          EXPSUM = 2*LEXP
00882       ELSE
00883          EXPSUM = 2*UEXP
00884       END IF
00885 *
00886 *     EXPSUM is the exponent range, approximately equal to
00887 *     EMAX - EMIN + 1 .
00888 *
00889       EMAX = EXPSUM + EMIN - 1
00890       NBITS = 1 + EXBITS + P
00891 *
00892 *     NBITS is the total number of bits needed to store a
00893 *     floating-point number.
00894 *
00895       IF( ( MOD( NBITS, 2 ).EQ.1 ) .AND. ( BETA.EQ.2 ) ) THEN
00896 *
00897 *        Either there are an odd number of bits used to store a
00898 *        floating-point number, which is unlikely, or some bits are
00899 *        not used in the representation of numbers, which is possible,
00900 *        (e.g. Cray machines) or the mantissa has an implicit bit,
00901 *        (e.g. IEEE machines, Dec Vax machines), which is perhaps the
00902 *        most likely. We have to assume the last alternative.
00903 *        If this is true, then we need to reduce EMAX by one because
00904 *        there must be some way of representing zero in an implicit-bit
00905 *        system. On machines like Cray, we are reducing EMAX by one
00906 *        unnecessarily.
00907 *
00908          EMAX = EMAX - 1
00909       END IF
00910 *
00911       IF( IEEE ) THEN
00912 *
00913 *        Assume we are on an IEEE machine which reserves one exponent
00914 *        for infinity and NaN.
00915 *
00916          EMAX = EMAX - 1
00917       END IF
00918 *
00919 *     Now create RMAX, the largest machine number, which should
00920 *     be equal to (1.0 - BETA**(-P)) * BETA**EMAX .
00921 *
00922 *     First compute 1.0 - BETA**(-P), being careful that the
00923 *     result is less than 1.0 .
00924 *
00925       RECBAS = ONE / BETA
00926       Z = BETA - ONE
00927       Y = ZERO
00928       DO 20 I = 1, P
00929          Z = Z*RECBAS
00930          IF( Y.LT.ONE )
00931      $      OLDY = Y
00932          Y = DLAMC3( Y, Z )
00933    20 CONTINUE
00934       IF( Y.GE.ONE )
00935      $   Y = OLDY
00936 *
00937 *     Now multiply by BETA**EMAX to get RMAX.
00938 *
00939       DO 30 I = 1, EMAX
00940          Y = DLAMC3( Y*BETA, ZERO )
00941    30 CONTINUE
00942 *
00943       RMAX = Y
00944       RETURN
00945 *
00946 *     End of DLAMC5
00947 *
00948       END
 All Files Functions