Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages | Examples

dlamch.c

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

Generated on Wed Sep 5 12:54:19 2007 for DSACSS Operational Code by  doxygen 1.3.9.1