annotate ext/cblas/src/dlamch.c @ 515:08bcc06c38ec tip master

Remove fast-math
author Chris Cannam <cannam@all-day-breakfast.com>
date Tue, 28 Jan 2020 15:27:37 +0000
parents 905e45637745
children
rev   line source
c@427 1 /* dlamch.f -- translated by f2c (version 20061008).
c@427 2 You must link the resulting object file with libf2c:
c@427 3 on Microsoft Windows system, link with libf2c.lib;
c@427 4 on Linux or Unix systems, link with .../path/to/libf2c.a -lm
c@427 5 or, if you install libf2c.a in a standard place, with -lf2c -lm
c@427 6 -- in that order, at the end of the command line, as in
c@427 7 cc *.o -lf2c -lm
c@427 8 Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
c@427 9
c@427 10 http://www.netlib.org/f2c/libf2c.zip
c@427 11 */
c@427 12
c@427 13 #include "f2c.h"
c@427 14 #include "blaswrap.h"
c@427 15
c@427 16 /* Table of constant values */
c@427 17
c@427 18 static integer c__1 = 1;
c@427 19 static doublereal c_b32 = 0.;
c@427 20
c@427 21 doublereal dlamch_(char *cmach)
c@427 22 {
c@427 23 /* Initialized data */
c@427 24
c@427 25 static logical first = TRUE_;
c@427 26
c@427 27 /* System generated locals */
c@427 28 integer i__1;
c@427 29 doublereal ret_val;
c@427 30
c@427 31 /* Builtin functions */
c@427 32 double pow_di(doublereal *, integer *);
c@427 33
c@427 34 /* Local variables */
c@427 35 static doublereal t;
c@427 36 integer it;
c@427 37 static doublereal rnd, eps, base;
c@427 38 integer beta;
c@427 39 static doublereal emin, prec, emax;
c@427 40 integer imin, imax;
c@427 41 logical lrnd;
c@427 42 static doublereal rmin, rmax;
c@427 43 doublereal rmach;
c@427 44 extern logical lsame_(char *, char *);
c@427 45 doublereal small;
c@427 46 static doublereal sfmin;
c@427 47 extern /* Subroutine */ int dlamc2_(integer *, integer *, logical *,
c@427 48 doublereal *, integer *, doublereal *, integer *, doublereal *);
c@427 49
c@427 50
c@427 51 /* -- LAPACK auxiliary routine (version 3.2) -- */
c@427 52 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
c@427 53 /* November 2006 */
c@427 54
c@427 55 /* .. Scalar Arguments .. */
c@427 56 /* .. */
c@427 57
c@427 58 /* Purpose */
c@427 59 /* ======= */
c@427 60
c@427 61 /* DLAMCH determines double precision machine parameters. */
c@427 62
c@427 63 /* Arguments */
c@427 64 /* ========= */
c@427 65
c@427 66 /* CMACH (input) CHARACTER*1 */
c@427 67 /* Specifies the value to be returned by DLAMCH: */
c@427 68 /* = 'E' or 'e', DLAMCH := eps */
c@427 69 /* = 'S' or 's , DLAMCH := sfmin */
c@427 70 /* = 'B' or 'b', DLAMCH := base */
c@427 71 /* = 'P' or 'p', DLAMCH := eps*base */
c@427 72 /* = 'N' or 'n', DLAMCH := t */
c@427 73 /* = 'R' or 'r', DLAMCH := rnd */
c@427 74 /* = 'M' or 'm', DLAMCH := emin */
c@427 75 /* = 'U' or 'u', DLAMCH := rmin */
c@427 76 /* = 'L' or 'l', DLAMCH := emax */
c@427 77 /* = 'O' or 'o', DLAMCH := rmax */
c@427 78
c@427 79 /* where */
c@427 80
c@427 81 /* eps = relative machine precision */
c@427 82 /* sfmin = safe minimum, such that 1/sfmin does not overflow */
c@427 83 /* base = base of the machine */
c@427 84 /* prec = eps*base */
c@427 85 /* t = number of (base) digits in the mantissa */
c@427 86 /* rnd = 1.0 when rounding occurs in addition, 0.0 otherwise */
c@427 87 /* emin = minimum exponent before (gradual) underflow */
c@427 88 /* rmin = underflow threshold - base**(emin-1) */
c@427 89 /* emax = largest exponent before overflow */
c@427 90 /* rmax = overflow threshold - (base**emax)*(1-eps) */
c@427 91
c@427 92 /* ===================================================================== */
c@427 93
c@427 94 /* .. Parameters .. */
c@427 95 /* .. */
c@427 96 /* .. Local Scalars .. */
c@427 97 /* .. */
c@427 98 /* .. External Functions .. */
c@427 99 /* .. */
c@427 100 /* .. External Subroutines .. */
c@427 101 /* .. */
c@427 102 /* .. Save statement .. */
c@427 103 /* .. */
c@427 104 /* .. Data statements .. */
c@427 105 /* .. */
c@427 106 /* .. Executable Statements .. */
c@427 107
c@427 108 if (first) {
c@427 109 dlamc2_(&beta, &it, &lrnd, &eps, &imin, &rmin, &imax, &rmax);
c@427 110 base = (doublereal) beta;
c@427 111 t = (doublereal) it;
c@427 112 if (lrnd) {
c@427 113 rnd = 1.;
c@427 114 i__1 = 1 - it;
c@427 115 eps = pow_di(&base, &i__1) / 2;
c@427 116 } else {
c@427 117 rnd = 0.;
c@427 118 i__1 = 1 - it;
c@427 119 eps = pow_di(&base, &i__1);
c@427 120 }
c@427 121 prec = eps * base;
c@427 122 emin = (doublereal) imin;
c@427 123 emax = (doublereal) imax;
c@427 124 sfmin = rmin;
c@427 125 small = 1. / rmax;
c@427 126 if (small >= sfmin) {
c@427 127
c@427 128 /* Use SMALL plus a bit, to avoid the possibility of rounding */
c@427 129 /* causing overflow when computing 1/sfmin. */
c@427 130
c@427 131 sfmin = small * (eps + 1.);
c@427 132 }
c@427 133 }
c@427 134
c@427 135 if (lsame_(cmach, "E")) {
c@427 136 rmach = eps;
c@427 137 } else if (lsame_(cmach, "S")) {
c@427 138 rmach = sfmin;
c@427 139 } else if (lsame_(cmach, "B")) {
c@427 140 rmach = base;
c@427 141 } else if (lsame_(cmach, "P")) {
c@427 142 rmach = prec;
c@427 143 } else if (lsame_(cmach, "N")) {
c@427 144 rmach = t;
c@427 145 } else if (lsame_(cmach, "R")) {
c@427 146 rmach = rnd;
c@427 147 } else if (lsame_(cmach, "M")) {
c@427 148 rmach = emin;
c@427 149 } else if (lsame_(cmach, "U")) {
c@427 150 rmach = rmin;
c@427 151 } else if (lsame_(cmach, "L")) {
c@427 152 rmach = emax;
c@427 153 } else if (lsame_(cmach, "O")) {
c@427 154 rmach = rmax;
c@427 155 }
c@427 156
c@427 157 ret_val = rmach;
c@427 158 first = FALSE_;
c@427 159 return ret_val;
c@427 160
c@427 161 /* End of DLAMCH */
c@427 162
c@427 163 } /* dlamch_ */
c@427 164
c@427 165
c@427 166 /* *********************************************************************** */
c@427 167
c@427 168 /* Subroutine */ int dlamc1_(integer *beta, integer *t, logical *rnd, logical
c@427 169 *ieee1)
c@427 170 {
c@427 171 /* Initialized data */
c@427 172
c@427 173 static logical first = TRUE_;
c@427 174
c@427 175 /* System generated locals */
c@427 176 doublereal d__1, d__2;
c@427 177
c@427 178 /* Local variables */
c@427 179 doublereal a, b, c__, f, t1, t2;
c@427 180 static integer lt;
c@427 181 doublereal one, qtr;
c@427 182 static logical lrnd;
c@427 183 static integer lbeta;
c@427 184 doublereal savec;
c@427 185 extern doublereal dlamc3_(doublereal *, doublereal *);
c@427 186 static logical lieee1;
c@427 187
c@427 188
c@427 189 /* -- LAPACK auxiliary routine (version 3.2) -- */
c@427 190 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
c@427 191 /* November 2006 */
c@427 192
c@427 193 /* .. Scalar Arguments .. */
c@427 194 /* .. */
c@427 195
c@427 196 /* Purpose */
c@427 197 /* ======= */
c@427 198
c@427 199 /* DLAMC1 determines the machine parameters given by BETA, T, RND, and */
c@427 200 /* IEEE1. */
c@427 201
c@427 202 /* Arguments */
c@427 203 /* ========= */
c@427 204
c@427 205 /* BETA (output) INTEGER */
c@427 206 /* The base of the machine. */
c@427 207
c@427 208 /* T (output) INTEGER */
c@427 209 /* The number of ( BETA ) digits in the mantissa. */
c@427 210
c@427 211 /* RND (output) LOGICAL */
c@427 212 /* Specifies whether proper rounding ( RND = .TRUE. ) or */
c@427 213 /* chopping ( RND = .FALSE. ) occurs in addition. This may not */
c@427 214 /* be a reliable guide to the way in which the machine performs */
c@427 215 /* its arithmetic. */
c@427 216
c@427 217 /* IEEE1 (output) LOGICAL */
c@427 218 /* Specifies whether rounding appears to be done in the IEEE */
c@427 219 /* 'round to nearest' style. */
c@427 220
c@427 221 /* Further Details */
c@427 222 /* =============== */
c@427 223
c@427 224 /* The routine is based on the routine ENVRON by Malcolm and */
c@427 225 /* incorporates suggestions by Gentleman and Marovich. See */
c@427 226
c@427 227 /* Malcolm M. A. (1972) Algorithms to reveal properties of */
c@427 228 /* floating-point arithmetic. Comms. of the ACM, 15, 949-951. */
c@427 229
c@427 230 /* Gentleman W. M. and Marovich S. B. (1974) More on algorithms */
c@427 231 /* that reveal properties of floating point arithmetic units. */
c@427 232 /* Comms. of the ACM, 17, 276-277. */
c@427 233
c@427 234 /* ===================================================================== */
c@427 235
c@427 236 /* .. Local Scalars .. */
c@427 237 /* .. */
c@427 238 /* .. External Functions .. */
c@427 239 /* .. */
c@427 240 /* .. Save statement .. */
c@427 241 /* .. */
c@427 242 /* .. Data statements .. */
c@427 243 /* .. */
c@427 244 /* .. Executable Statements .. */
c@427 245
c@427 246 if (first) {
c@427 247 one = 1.;
c@427 248
c@427 249 /* LBETA, LIEEE1, LT and LRND are the local values of BETA, */
c@427 250 /* IEEE1, T and RND. */
c@427 251
c@427 252 /* Throughout this routine we use the function DLAMC3 to ensure */
c@427 253 /* that relevant values are stored and not held in registers, or */
c@427 254 /* are not affected by optimizers. */
c@427 255
c@427 256 /* Compute a = 2.0**m with the smallest positive integer m such */
c@427 257 /* that */
c@427 258
c@427 259 /* fl( a + 1.0 ) = a. */
c@427 260
c@427 261 a = 1.;
c@427 262 c__ = 1.;
c@427 263
c@427 264 /* + WHILE( C.EQ.ONE )LOOP */
c@427 265 L10:
c@427 266 if (c__ == one) {
c@427 267 a *= 2;
c@427 268 c__ = dlamc3_(&a, &one);
c@427 269 d__1 = -a;
c@427 270 c__ = dlamc3_(&c__, &d__1);
c@427 271 goto L10;
c@427 272 }
c@427 273 /* + END WHILE */
c@427 274
c@427 275 /* Now compute b = 2.0**m with the smallest positive integer m */
c@427 276 /* such that */
c@427 277
c@427 278 /* fl( a + b ) .gt. a. */
c@427 279
c@427 280 b = 1.;
c@427 281 c__ = dlamc3_(&a, &b);
c@427 282
c@427 283 /* + WHILE( C.EQ.A )LOOP */
c@427 284 L20:
c@427 285 if (c__ == a) {
c@427 286 b *= 2;
c@427 287 c__ = dlamc3_(&a, &b);
c@427 288 goto L20;
c@427 289 }
c@427 290 /* + END WHILE */
c@427 291
c@427 292 /* Now compute the base. a and c are neighbouring floating point */
c@427 293 /* numbers in the interval ( beta**t, beta**( t + 1 ) ) and so */
c@427 294 /* their difference is beta. Adding 0.25 to c is to ensure that it */
c@427 295 /* is truncated to beta and not ( beta - 1 ). */
c@427 296
c@427 297 qtr = one / 4;
c@427 298 savec = c__;
c@427 299 d__1 = -a;
c@427 300 c__ = dlamc3_(&c__, &d__1);
c@427 301 lbeta = (integer) (c__ + qtr);
c@427 302
c@427 303 /* Now determine whether rounding or chopping occurs, by adding a */
c@427 304 /* bit less than beta/2 and a bit more than beta/2 to a. */
c@427 305
c@427 306 b = (doublereal) lbeta;
c@427 307 d__1 = b / 2;
c@427 308 d__2 = -b / 100;
c@427 309 f = dlamc3_(&d__1, &d__2);
c@427 310 c__ = dlamc3_(&f, &a);
c@427 311 if (c__ == a) {
c@427 312 lrnd = TRUE_;
c@427 313 } else {
c@427 314 lrnd = FALSE_;
c@427 315 }
c@427 316 d__1 = b / 2;
c@427 317 d__2 = b / 100;
c@427 318 f = dlamc3_(&d__1, &d__2);
c@427 319 c__ = dlamc3_(&f, &a);
c@427 320 if (lrnd && c__ == a) {
c@427 321 lrnd = FALSE_;
c@427 322 }
c@427 323
c@427 324 /* Try and decide whether rounding is done in the IEEE 'round to */
c@427 325 /* nearest' style. B/2 is half a unit in the last place of the two */
c@427 326 /* numbers A and SAVEC. Furthermore, A is even, i.e. has last bit */
c@427 327 /* zero, and SAVEC is odd. Thus adding B/2 to A should not change */
c@427 328 /* A, but adding B/2 to SAVEC should change SAVEC. */
c@427 329
c@427 330 d__1 = b / 2;
c@427 331 t1 = dlamc3_(&d__1, &a);
c@427 332 d__1 = b / 2;
c@427 333 t2 = dlamc3_(&d__1, &savec);
c@427 334 lieee1 = t1 == a && t2 > savec && lrnd;
c@427 335
c@427 336 /* Now find the mantissa, t. It should be the integer part of */
c@427 337 /* log to the base beta of a, however it is safer to determine t */
c@427 338 /* by powering. So we find t as the smallest positive integer for */
c@427 339 /* which */
c@427 340
c@427 341 /* fl( beta**t + 1.0 ) = 1.0. */
c@427 342
c@427 343 lt = 0;
c@427 344 a = 1.;
c@427 345 c__ = 1.;
c@427 346
c@427 347 /* + WHILE( C.EQ.ONE )LOOP */
c@427 348 L30:
c@427 349 if (c__ == one) {
c@427 350 ++lt;
c@427 351 a *= lbeta;
c@427 352 c__ = dlamc3_(&a, &one);
c@427 353 d__1 = -a;
c@427 354 c__ = dlamc3_(&c__, &d__1);
c@427 355 goto L30;
c@427 356 }
c@427 357 /* + END WHILE */
c@427 358
c@427 359 }
c@427 360
c@427 361 *beta = lbeta;
c@427 362 *t = lt;
c@427 363 *rnd = lrnd;
c@427 364 *ieee1 = lieee1;
c@427 365 first = FALSE_;
c@427 366 return 0;
c@427 367
c@427 368 /* End of DLAMC1 */
c@427 369
c@427 370 } /* dlamc1_ */
c@427 371
c@427 372
c@427 373 /* *********************************************************************** */
c@427 374
c@427 375 /* Subroutine */ int dlamc2_(integer *beta, integer *t, logical *rnd,
c@427 376 doublereal *eps, integer *emin, doublereal *rmin, integer *emax,
c@427 377 doublereal *rmax)
c@427 378 {
c@427 379 /* Initialized data */
c@427 380
c@427 381 static logical first = TRUE_;
c@427 382 static logical iwarn = FALSE_;
c@427 383
c@427 384 /* Format strings */
c@427 385 static char fmt_9999[] = "(//\002 WARNING. The value EMIN may be incorre"
c@427 386 "ct:-\002,\002 EMIN = \002,i8,/\002 If, after inspection, the va"
c@427 387 "lue EMIN looks\002,\002 acceptable please comment out \002,/\002"
c@427 388 " the IF block as marked within the code of routine\002,\002 DLAM"
c@427 389 "C2,\002,/\002 otherwise supply EMIN explicitly.\002,/)";
c@427 390
c@427 391 /* System generated locals */
c@427 392 integer i__1;
c@427 393 doublereal d__1, d__2, d__3, d__4, d__5;
c@427 394
c@427 395 /* Builtin functions */
c@427 396 double pow_di(doublereal *, integer *);
c@427 397 integer s_wsfe(cilist *), do_fio(integer *, char *, ftnlen), e_wsfe(void);
c@427 398
c@427 399 /* Local variables */
c@427 400 doublereal a, b, c__;
c@427 401 integer i__;
c@427 402 static integer lt;
c@427 403 doublereal one, two;
c@427 404 logical ieee;
c@427 405 doublereal half;
c@427 406 logical lrnd;
c@427 407 static doublereal leps;
c@427 408 doublereal zero;
c@427 409 static integer lbeta;
c@427 410 doublereal rbase;
c@427 411 static integer lemin, lemax;
c@427 412 integer gnmin;
c@427 413 doublereal small;
c@427 414 integer gpmin;
c@427 415 doublereal third;
c@427 416 static doublereal lrmin, lrmax;
c@427 417 doublereal sixth;
c@427 418 extern /* Subroutine */ int dlamc1_(integer *, integer *, logical *,
c@427 419 logical *);
c@427 420 extern doublereal dlamc3_(doublereal *, doublereal *);
c@427 421 logical lieee1;
c@427 422 extern /* Subroutine */ int dlamc4_(integer *, doublereal *, integer *),
c@427 423 dlamc5_(integer *, integer *, integer *, logical *, integer *,
c@427 424 doublereal *);
c@427 425 integer ngnmin, ngpmin;
c@427 426
c@427 427 /* Fortran I/O blocks */
c@427 428 static cilist io___58 = { 0, 6, 0, fmt_9999, 0 };
c@427 429
c@427 430
c@427 431
c@427 432 /* -- LAPACK auxiliary routine (version 3.2) -- */
c@427 433 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
c@427 434 /* November 2006 */
c@427 435
c@427 436 /* .. Scalar Arguments .. */
c@427 437 /* .. */
c@427 438
c@427 439 /* Purpose */
c@427 440 /* ======= */
c@427 441
c@427 442 /* DLAMC2 determines the machine parameters specified in its argument */
c@427 443 /* list. */
c@427 444
c@427 445 /* Arguments */
c@427 446 /* ========= */
c@427 447
c@427 448 /* BETA (output) INTEGER */
c@427 449 /* The base of the machine. */
c@427 450
c@427 451 /* T (output) INTEGER */
c@427 452 /* The number of ( BETA ) digits in the mantissa. */
c@427 453
c@427 454 /* RND (output) LOGICAL */
c@427 455 /* Specifies whether proper rounding ( RND = .TRUE. ) or */
c@427 456 /* chopping ( RND = .FALSE. ) occurs in addition. This may not */
c@427 457 /* be a reliable guide to the way in which the machine performs */
c@427 458 /* its arithmetic. */
c@427 459
c@427 460 /* EPS (output) DOUBLE PRECISION */
c@427 461 /* The smallest positive number such that */
c@427 462
c@427 463 /* fl( 1.0 - EPS ) .LT. 1.0, */
c@427 464
c@427 465 /* where fl denotes the computed value. */
c@427 466
c@427 467 /* EMIN (output) INTEGER */
c@427 468 /* The minimum exponent before (gradual) underflow occurs. */
c@427 469
c@427 470 /* RMIN (output) DOUBLE PRECISION */
c@427 471 /* The smallest normalized number for the machine, given by */
c@427 472 /* BASE**( EMIN - 1 ), where BASE is the floating point value */
c@427 473 /* of BETA. */
c@427 474
c@427 475 /* EMAX (output) INTEGER */
c@427 476 /* The maximum exponent before overflow occurs. */
c@427 477
c@427 478 /* RMAX (output) DOUBLE PRECISION */
c@427 479 /* The largest positive number for the machine, given by */
c@427 480 /* BASE**EMAX * ( 1 - EPS ), where BASE is the floating point */
c@427 481 /* value of BETA. */
c@427 482
c@427 483 /* Further Details */
c@427 484 /* =============== */
c@427 485
c@427 486 /* The computation of EPS is based on a routine PARANOIA by */
c@427 487 /* W. Kahan of the University of California at Berkeley. */
c@427 488
c@427 489 /* ===================================================================== */
c@427 490
c@427 491 /* .. Local Scalars .. */
c@427 492 /* .. */
c@427 493 /* .. External Functions .. */
c@427 494 /* .. */
c@427 495 /* .. External Subroutines .. */
c@427 496 /* .. */
c@427 497 /* .. Intrinsic Functions .. */
c@427 498 /* .. */
c@427 499 /* .. Save statement .. */
c@427 500 /* .. */
c@427 501 /* .. Data statements .. */
c@427 502 /* .. */
c@427 503 /* .. Executable Statements .. */
c@427 504
c@427 505 if (first) {
c@427 506 zero = 0.;
c@427 507 one = 1.;
c@427 508 two = 2.;
c@427 509
c@427 510 /* LBETA, LT, LRND, LEPS, LEMIN and LRMIN are the local values of */
c@427 511 /* BETA, T, RND, EPS, EMIN and RMIN. */
c@427 512
c@427 513 /* Throughout this routine we use the function DLAMC3 to ensure */
c@427 514 /* that relevant values are stored and not held in registers, or */
c@427 515 /* are not affected by optimizers. */
c@427 516
c@427 517 /* DLAMC1 returns the parameters LBETA, LT, LRND and LIEEE1. */
c@427 518
c@427 519 dlamc1_(&lbeta, &lt, &lrnd, &lieee1);
c@427 520
c@427 521 /* Start to find EPS. */
c@427 522
c@427 523 b = (doublereal) lbeta;
c@427 524 i__1 = -lt;
c@427 525 a = pow_di(&b, &i__1);
c@427 526 leps = a;
c@427 527
c@427 528 /* Try some tricks to see whether or not this is the correct EPS. */
c@427 529
c@427 530 b = two / 3;
c@427 531 half = one / 2;
c@427 532 d__1 = -half;
c@427 533 sixth = dlamc3_(&b, &d__1);
c@427 534 third = dlamc3_(&sixth, &sixth);
c@427 535 d__1 = -half;
c@427 536 b = dlamc3_(&third, &d__1);
c@427 537 b = dlamc3_(&b, &sixth);
c@427 538 b = abs(b);
c@427 539 if (b < leps) {
c@427 540 b = leps;
c@427 541 }
c@427 542
c@427 543 leps = 1.;
c@427 544
c@427 545 /* + WHILE( ( LEPS.GT.B ).AND.( B.GT.ZERO ) )LOOP */
c@427 546 L10:
c@427 547 if (leps > b && b > zero) {
c@427 548 leps = b;
c@427 549 d__1 = half * leps;
c@427 550 /* Computing 5th power */
c@427 551 d__3 = two, d__4 = d__3, d__3 *= d__3;
c@427 552 /* Computing 2nd power */
c@427 553 d__5 = leps;
c@427 554 d__2 = d__4 * (d__3 * d__3) * (d__5 * d__5);
c@427 555 c__ = dlamc3_(&d__1, &d__2);
c@427 556 d__1 = -c__;
c@427 557 c__ = dlamc3_(&half, &d__1);
c@427 558 b = dlamc3_(&half, &c__);
c@427 559 d__1 = -b;
c@427 560 c__ = dlamc3_(&half, &d__1);
c@427 561 b = dlamc3_(&half, &c__);
c@427 562 goto L10;
c@427 563 }
c@427 564 /* + END WHILE */
c@427 565
c@427 566 if (a < leps) {
c@427 567 leps = a;
c@427 568 }
c@427 569
c@427 570 /* Computation of EPS complete. */
c@427 571
c@427 572 /* Now find EMIN. Let A = + or - 1, and + or - (1 + BASE**(-3)). */
c@427 573 /* Keep dividing A by BETA until (gradual) underflow occurs. This */
c@427 574 /* is detected when we cannot recover the previous A. */
c@427 575
c@427 576 rbase = one / lbeta;
c@427 577 small = one;
c@427 578 for (i__ = 1; i__ <= 3; ++i__) {
c@427 579 d__1 = small * rbase;
c@427 580 small = dlamc3_(&d__1, &zero);
c@427 581 /* L20: */
c@427 582 }
c@427 583 a = dlamc3_(&one, &small);
c@427 584 dlamc4_(&ngpmin, &one, &lbeta);
c@427 585 d__1 = -one;
c@427 586 dlamc4_(&ngnmin, &d__1, &lbeta);
c@427 587 dlamc4_(&gpmin, &a, &lbeta);
c@427 588 d__1 = -a;
c@427 589 dlamc4_(&gnmin, &d__1, &lbeta);
c@427 590 ieee = FALSE_;
c@427 591
c@427 592 if (ngpmin == ngnmin && gpmin == gnmin) {
c@427 593 if (ngpmin == gpmin) {
c@427 594 lemin = ngpmin;
c@427 595 /* ( Non twos-complement machines, no gradual underflow; */
c@427 596 /* e.g., VAX ) */
c@427 597 } else if (gpmin - ngpmin == 3) {
c@427 598 lemin = ngpmin - 1 + lt;
c@427 599 ieee = TRUE_;
c@427 600 /* ( Non twos-complement machines, with gradual underflow; */
c@427 601 /* e.g., IEEE standard followers ) */
c@427 602 } else {
c@427 603 lemin = min(ngpmin,gpmin);
c@427 604 /* ( A guess; no known machine ) */
c@427 605 iwarn = TRUE_;
c@427 606 }
c@427 607
c@427 608 } else if (ngpmin == gpmin && ngnmin == gnmin) {
c@427 609 if ((i__1 = ngpmin - ngnmin, abs(i__1)) == 1) {
c@427 610 lemin = max(ngpmin,ngnmin);
c@427 611 /* ( Twos-complement machines, no gradual underflow; */
c@427 612 /* e.g., CYBER 205 ) */
c@427 613 } else {
c@427 614 lemin = min(ngpmin,ngnmin);
c@427 615 /* ( A guess; no known machine ) */
c@427 616 iwarn = TRUE_;
c@427 617 }
c@427 618
c@427 619 } else if ((i__1 = ngpmin - ngnmin, abs(i__1)) == 1 && gpmin == gnmin)
c@427 620 {
c@427 621 if (gpmin - min(ngpmin,ngnmin) == 3) {
c@427 622 lemin = max(ngpmin,ngnmin) - 1 + lt;
c@427 623 /* ( Twos-complement machines with gradual underflow; */
c@427 624 /* no known machine ) */
c@427 625 } else {
c@427 626 lemin = min(ngpmin,ngnmin);
c@427 627 /* ( A guess; no known machine ) */
c@427 628 iwarn = TRUE_;
c@427 629 }
c@427 630
c@427 631 } else {
c@427 632 /* Computing MIN */
c@427 633 i__1 = min(ngpmin,ngnmin), i__1 = min(i__1,gpmin);
c@427 634 lemin = min(i__1,gnmin);
c@427 635 /* ( A guess; no known machine ) */
c@427 636 iwarn = TRUE_;
c@427 637 }
c@427 638 first = FALSE_;
c@427 639 /* ** */
c@427 640 /* Comment out this if block if EMIN is ok */
c@427 641 if (iwarn) {
c@427 642 first = TRUE_;
c@427 643 s_wsfe(&io___58);
c@427 644 do_fio(&c__1, (char *)&lemin, (ftnlen)sizeof(integer));
c@427 645 e_wsfe();
c@427 646 }
c@427 647 /* ** */
c@427 648
c@427 649 /* Assume IEEE arithmetic if we found denormalised numbers above, */
c@427 650 /* or if arithmetic seems to round in the IEEE style, determined */
c@427 651 /* in routine DLAMC1. A true IEEE machine should have both things */
c@427 652 /* true; however, faulty machines may have one or the other. */
c@427 653
c@427 654 ieee = ieee || lieee1;
c@427 655
c@427 656 /* Compute RMIN by successive division by BETA. We could compute */
c@427 657 /* RMIN as BASE**( EMIN - 1 ), but some machines underflow during */
c@427 658 /* this computation. */
c@427 659
c@427 660 lrmin = 1.;
c@427 661 i__1 = 1 - lemin;
c@427 662 for (i__ = 1; i__ <= i__1; ++i__) {
c@427 663 d__1 = lrmin * rbase;
c@427 664 lrmin = dlamc3_(&d__1, &zero);
c@427 665 /* L30: */
c@427 666 }
c@427 667
c@427 668 /* Finally, call DLAMC5 to compute EMAX and RMAX. */
c@427 669
c@427 670 dlamc5_(&lbeta, &lt, &lemin, &ieee, &lemax, &lrmax);
c@427 671 }
c@427 672
c@427 673 *beta = lbeta;
c@427 674 *t = lt;
c@427 675 *rnd = lrnd;
c@427 676 *eps = leps;
c@427 677 *emin = lemin;
c@427 678 *rmin = lrmin;
c@427 679 *emax = lemax;
c@427 680 *rmax = lrmax;
c@427 681
c@427 682 return 0;
c@427 683
c@427 684
c@427 685 /* End of DLAMC2 */
c@427 686
c@427 687 } /* dlamc2_ */
c@427 688
c@427 689
c@427 690 /* *********************************************************************** */
c@427 691
c@427 692 doublereal dlamc3_(doublereal *a, doublereal *b)
c@427 693 {
c@427 694 /* System generated locals */
c@427 695 doublereal ret_val;
c@427 696
c@427 697
c@427 698 /* -- LAPACK auxiliary routine (version 3.2) -- */
c@427 699 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
c@427 700 /* November 2006 */
c@427 701
c@427 702 /* .. Scalar Arguments .. */
c@427 703 /* .. */
c@427 704
c@427 705 /* Purpose */
c@427 706 /* ======= */
c@427 707
c@427 708 /* DLAMC3 is intended to force A and B to be stored prior to doing */
c@427 709 /* the addition of A and B , for use in situations where optimizers */
c@427 710 /* might hold one of these in a register. */
c@427 711
c@427 712 /* Arguments */
c@427 713 /* ========= */
c@427 714
c@427 715 /* A (input) DOUBLE PRECISION */
c@427 716 /* B (input) DOUBLE PRECISION */
c@427 717 /* The values A and B. */
c@427 718
c@427 719 /* ===================================================================== */
c@427 720
c@427 721 /* .. Executable Statements .. */
c@427 722
c@427 723 ret_val = *a + *b;
c@427 724
c@427 725 return ret_val;
c@427 726
c@427 727 /* End of DLAMC3 */
c@427 728
c@427 729 } /* dlamc3_ */
c@427 730
c@427 731
c@427 732 /* *********************************************************************** */
c@427 733
c@427 734 /* Subroutine */ int dlamc4_(integer *emin, doublereal *start, integer *base)
c@427 735 {
c@427 736 /* System generated locals */
c@427 737 integer i__1;
c@427 738 doublereal d__1;
c@427 739
c@427 740 /* Local variables */
c@427 741 doublereal a;
c@427 742 integer i__;
c@427 743 doublereal b1, b2, c1, c2, d1, d2, one, zero, rbase;
c@427 744 extern doublereal dlamc3_(doublereal *, doublereal *);
c@427 745
c@427 746
c@427 747 /* -- LAPACK auxiliary routine (version 3.2) -- */
c@427 748 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
c@427 749 /* November 2006 */
c@427 750
c@427 751 /* .. Scalar Arguments .. */
c@427 752 /* .. */
c@427 753
c@427 754 /* Purpose */
c@427 755 /* ======= */
c@427 756
c@427 757 /* DLAMC4 is a service routine for DLAMC2. */
c@427 758
c@427 759 /* Arguments */
c@427 760 /* ========= */
c@427 761
c@427 762 /* EMIN (output) INTEGER */
c@427 763 /* The minimum exponent before (gradual) underflow, computed by */
c@427 764 /* setting A = START and dividing by BASE until the previous A */
c@427 765 /* can not be recovered. */
c@427 766
c@427 767 /* START (input) DOUBLE PRECISION */
c@427 768 /* The starting point for determining EMIN. */
c@427 769
c@427 770 /* BASE (input) INTEGER */
c@427 771 /* The base of the machine. */
c@427 772
c@427 773 /* ===================================================================== */
c@427 774
c@427 775 /* .. Local Scalars .. */
c@427 776 /* .. */
c@427 777 /* .. External Functions .. */
c@427 778 /* .. */
c@427 779 /* .. Executable Statements .. */
c@427 780
c@427 781 a = *start;
c@427 782 one = 1.;
c@427 783 rbase = one / *base;
c@427 784 zero = 0.;
c@427 785 *emin = 1;
c@427 786 d__1 = a * rbase;
c@427 787 b1 = dlamc3_(&d__1, &zero);
c@427 788 c1 = a;
c@427 789 c2 = a;
c@427 790 d1 = a;
c@427 791 d2 = a;
c@427 792 /* + WHILE( ( C1.EQ.A ).AND.( C2.EQ.A ).AND. */
c@427 793 /* $ ( D1.EQ.A ).AND.( D2.EQ.A ) )LOOP */
c@427 794 L10:
c@427 795 if (c1 == a && c2 == a && d1 == a && d2 == a) {
c@427 796 --(*emin);
c@427 797 a = b1;
c@427 798 d__1 = a / *base;
c@427 799 b1 = dlamc3_(&d__1, &zero);
c@427 800 d__1 = b1 * *base;
c@427 801 c1 = dlamc3_(&d__1, &zero);
c@427 802 d1 = zero;
c@427 803 i__1 = *base;
c@427 804 for (i__ = 1; i__ <= i__1; ++i__) {
c@427 805 d1 += b1;
c@427 806 /* L20: */
c@427 807 }
c@427 808 d__1 = a * rbase;
c@427 809 b2 = dlamc3_(&d__1, &zero);
c@427 810 d__1 = b2 / rbase;
c@427 811 c2 = dlamc3_(&d__1, &zero);
c@427 812 d2 = zero;
c@427 813 i__1 = *base;
c@427 814 for (i__ = 1; i__ <= i__1; ++i__) {
c@427 815 d2 += b2;
c@427 816 /* L30: */
c@427 817 }
c@427 818 goto L10;
c@427 819 }
c@427 820 /* + END WHILE */
c@427 821
c@427 822 return 0;
c@427 823
c@427 824 /* End of DLAMC4 */
c@427 825
c@427 826 } /* dlamc4_ */
c@427 827
c@427 828
c@427 829 /* *********************************************************************** */
c@427 830
c@427 831 /* Subroutine */ int dlamc5_(integer *beta, integer *p, integer *emin,
c@427 832 logical *ieee, integer *emax, doublereal *rmax)
c@427 833 {
c@427 834 /* System generated locals */
c@427 835 integer i__1;
c@427 836 doublereal d__1;
c@427 837
c@427 838 /* Local variables */
c@427 839 integer i__;
c@427 840 doublereal y, z__;
c@427 841 integer try__, lexp;
c@427 842 doublereal oldy;
c@427 843 integer uexp, nbits;
c@427 844 extern doublereal dlamc3_(doublereal *, doublereal *);
c@427 845 doublereal recbas;
c@427 846 integer exbits, expsum;
c@427 847
c@427 848
c@427 849 /* -- LAPACK auxiliary routine (version 3.2) -- */
c@427 850 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
c@427 851 /* November 2006 */
c@427 852
c@427 853 /* .. Scalar Arguments .. */
c@427 854 /* .. */
c@427 855
c@427 856 /* Purpose */
c@427 857 /* ======= */
c@427 858
c@427 859 /* DLAMC5 attempts to compute RMAX, the largest machine floating-point */
c@427 860 /* number, without overflow. It assumes that EMAX + abs(EMIN) sum */
c@427 861 /* approximately to a power of 2. It will fail on machines where this */
c@427 862 /* assumption does not hold, for example, the Cyber 205 (EMIN = -28625, */
c@427 863 /* EMAX = 28718). It will also fail if the value supplied for EMIN is */
c@427 864 /* too large (i.e. too close to zero), probably with overflow. */
c@427 865
c@427 866 /* Arguments */
c@427 867 /* ========= */
c@427 868
c@427 869 /* BETA (input) INTEGER */
c@427 870 /* The base of floating-point arithmetic. */
c@427 871
c@427 872 /* P (input) INTEGER */
c@427 873 /* The number of base BETA digits in the mantissa of a */
c@427 874 /* floating-point value. */
c@427 875
c@427 876 /* EMIN (input) INTEGER */
c@427 877 /* The minimum exponent before (gradual) underflow. */
c@427 878
c@427 879 /* IEEE (input) LOGICAL */
c@427 880 /* A logical flag specifying whether or not the arithmetic */
c@427 881 /* system is thought to comply with the IEEE standard. */
c@427 882
c@427 883 /* EMAX (output) INTEGER */
c@427 884 /* The largest exponent before overflow */
c@427 885
c@427 886 /* RMAX (output) DOUBLE PRECISION */
c@427 887 /* The largest machine floating-point number. */
c@427 888
c@427 889 /* ===================================================================== */
c@427 890
c@427 891 /* .. Parameters .. */
c@427 892 /* .. */
c@427 893 /* .. Local Scalars .. */
c@427 894 /* .. */
c@427 895 /* .. External Functions .. */
c@427 896 /* .. */
c@427 897 /* .. Intrinsic Functions .. */
c@427 898 /* .. */
c@427 899 /* .. Executable Statements .. */
c@427 900
c@427 901 /* First compute LEXP and UEXP, two powers of 2 that bound */
c@427 902 /* abs(EMIN). We then assume that EMAX + abs(EMIN) will sum */
c@427 903 /* approximately to the bound that is closest to abs(EMIN). */
c@427 904 /* (EMAX is the exponent of the required number RMAX). */
c@427 905
c@427 906 lexp = 1;
c@427 907 exbits = 1;
c@427 908 L10:
c@427 909 try__ = lexp << 1;
c@427 910 if (try__ <= -(*emin)) {
c@427 911 lexp = try__;
c@427 912 ++exbits;
c@427 913 goto L10;
c@427 914 }
c@427 915 if (lexp == -(*emin)) {
c@427 916 uexp = lexp;
c@427 917 } else {
c@427 918 uexp = try__;
c@427 919 ++exbits;
c@427 920 }
c@427 921
c@427 922 /* Now -LEXP is less than or equal to EMIN, and -UEXP is greater */
c@427 923 /* than or equal to EMIN. EXBITS is the number of bits needed to */
c@427 924 /* store the exponent. */
c@427 925
c@427 926 if (uexp + *emin > -lexp - *emin) {
c@427 927 expsum = lexp << 1;
c@427 928 } else {
c@427 929 expsum = uexp << 1;
c@427 930 }
c@427 931
c@427 932 /* EXPSUM is the exponent range, approximately equal to */
c@427 933 /* EMAX - EMIN + 1 . */
c@427 934
c@427 935 *emax = expsum + *emin - 1;
c@427 936 nbits = exbits + 1 + *p;
c@427 937
c@427 938 /* NBITS is the total number of bits needed to store a */
c@427 939 /* floating-point number. */
c@427 940
c@427 941 if (nbits % 2 == 1 && *beta == 2) {
c@427 942
c@427 943 /* Either there are an odd number of bits used to store a */
c@427 944 /* floating-point number, which is unlikely, or some bits are */
c@427 945 /* not used in the representation of numbers, which is possible, */
c@427 946 /* (e.g. Cray machines) or the mantissa has an implicit bit, */
c@427 947 /* (e.g. IEEE machines, Dec Vax machines), which is perhaps the */
c@427 948 /* most likely. We have to assume the last alternative. */
c@427 949 /* If this is true, then we need to reduce EMAX by one because */
c@427 950 /* there must be some way of representing zero in an implicit-bit */
c@427 951 /* system. On machines like Cray, we are reducing EMAX by one */
c@427 952 /* unnecessarily. */
c@427 953
c@427 954 --(*emax);
c@427 955 }
c@427 956
c@427 957 if (*ieee) {
c@427 958
c@427 959 /* Assume we are on an IEEE machine which reserves one exponent */
c@427 960 /* for infinity and NaN. */
c@427 961
c@427 962 --(*emax);
c@427 963 }
c@427 964
c@427 965 /* Now create RMAX, the largest machine number, which should */
c@427 966 /* be equal to (1.0 - BETA**(-P)) * BETA**EMAX . */
c@427 967
c@427 968 /* First compute 1.0 - BETA**(-P), being careful that the */
c@427 969 /* result is less than 1.0 . */
c@427 970
c@427 971 recbas = 1. / *beta;
c@427 972 z__ = *beta - 1.;
c@427 973 y = 0.;
c@427 974 i__1 = *p;
c@427 975 for (i__ = 1; i__ <= i__1; ++i__) {
c@427 976 z__ *= recbas;
c@427 977 if (y < 1.) {
c@427 978 oldy = y;
c@427 979 }
c@427 980 y = dlamc3_(&y, &z__);
c@427 981 /* L20: */
c@427 982 }
c@427 983 if (y >= 1.) {
c@427 984 y = oldy;
c@427 985 }
c@427 986
c@427 987 /* Now multiply by BETA**EMAX to get RMAX. */
c@427 988
c@427 989 i__1 = *emax;
c@427 990 for (i__ = 1; i__ <= i__1; ++i__) {
c@427 991 d__1 = y * *beta;
c@427 992 y = dlamc3_(&d__1, &c_b32);
c@427 993 /* L30: */
c@427 994 }
c@427 995
c@427 996 *rmax = y;
c@427 997 return 0;
c@427 998
c@427 999 /* End of DLAMC5 */
c@427 1000
c@427 1001 } /* dlamc5_ */