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