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