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


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:55:46