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, <, &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, <, &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