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, <, &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, <, &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_ */