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