00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004
00005 #include <float.h>
00006
00007 #ifndef TEST
00008 #include "f77-fcn.h"
00009 #endif
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifdef SP
00020 #define REAL float
00021 #define ZERO 0.0
00022 #define ONE 1.0
00023 #define PREC "Single "
00024 #define REALSIZE 1
00025 #endif
00026
00027 #ifdef DP
00028 #define REAL double
00029 #define ZERO 0.0e0
00030 #define ONE 1.0e0
00031 #define PREC "Double "
00032 #define REALSIZE 2
00033 #endif
00034
00035 #include <math.h>
00036 #include <stdio.h>
00037
00038 #define ABS(xxx) ((xxx>ZERO)?(xxx):(-xxx))
00039
00040 void
00041 rmachar(int *ibeta, int *it, int *irnd, int *ngrd, int *machep,
00042 int *negep, int *iexp, int *minexp, int *maxexp, REAL *eps,
00043 REAL *epsneg, REAL *xmin, REAL *xmax)
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 {
00126 int i,iz,j,k;
00127 int mx,itmp,nxres;
00128 volatile REAL a,b,beta,betain,one,y,z,zero;
00129 volatile REAL betah,two,t,tmp,tmpa,tmp1;
00130
00131 (*irnd) = 1;
00132 one = (REAL)(*irnd);
00133 two = one + one;
00134 a = two;
00135 b = a;
00136 zero = 0.0e0;
00137
00138
00139
00140
00141
00142 tmp = ((a+one)-a)-one;
00143
00144 while (tmp == zero) {
00145 a = a+a;
00146 tmp = a+one;
00147 tmp1 = tmp-a;
00148 tmp = tmp1-one;
00149 }
00150
00151 tmp = a+b;
00152 itmp = (int)(tmp-a);
00153 while (itmp == 0) {
00154 b = b+b;
00155 tmp = a+b;
00156 itmp = (int)(tmp-a);
00157 }
00158
00159 *ibeta = itmp;
00160 beta = (REAL)(*ibeta);
00161
00162
00163
00164
00165
00166 (*it) = 0;
00167 b = one;
00168 tmp = ((b+one)-b)-one;
00169
00170 while (tmp == zero) {
00171 *it = *it+1;
00172 b = b*beta;
00173 tmp = b+one;
00174 tmp1 = tmp-b;
00175 tmp = tmp1-one;
00176 }
00177
00178 *irnd = 0;
00179 betah = beta/two;
00180 tmp = a+betah;
00181 tmp1 = tmp-a;
00182 if (tmp1 != zero) *irnd = 1;
00183 tmpa = a+beta;
00184 tmp = tmpa+betah;
00185 if ((*irnd == 0) && (tmp-tmpa != zero)) *irnd = 2;
00186
00187
00188
00189
00190
00191 (*negep) = (*it) + 3;
00192 betain = one / beta;
00193 a = one;
00194
00195 for (i = 1; i<=(*negep); i++) {
00196 a = a * betain;
00197 }
00198
00199 b = a;
00200 tmp = (one-a);
00201 tmp = tmp-one;
00202
00203 while (tmp == zero) {
00204 a = a*beta;
00205 *negep = *negep-1;
00206 tmp1 = one-a;
00207 tmp = tmp1-one;
00208 }
00209
00210 (*negep) = -(*negep);
00211 (*epsneg) = a;
00212
00213
00214
00215
00216
00217 (*machep) = -(*it) - 3;
00218 a = b;
00219 tmp = one+a;
00220
00221 while (tmp-one == zero) {
00222 a = a*beta;
00223 *machep = *machep+1;
00224 tmp = one+a;
00225 }
00226
00227 *eps = a;
00228
00229
00230
00231
00232
00233 (*ngrd) = 0;
00234 tmp = one+*eps;
00235 tmp = tmp*one;
00236 if (((*irnd) == 0) && (tmp-one) != zero) (*ngrd) = 1;
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 i = 0;
00248 k = 1;
00249 z = betain;
00250 t = one+*eps;
00251 nxres = 0;
00252
00253 for (;;) {
00254 y = z;
00255 z = y * y;
00256
00257
00258
00259
00260
00261 a = z * one;
00262 tmp = z*t;
00263 if ((a+a == zero) || (ABS(z) > y)) break;
00264 tmp1 = tmp*betain;
00265 if (tmp1*beta == z) break;
00266 i = i + 1;
00267 k = k+k;
00268 }
00269
00270
00271
00272
00273
00274
00275 (*iexp) = i + 1;
00276 mx = k + k;
00277 if (*ibeta == 10) {
00278
00279
00280
00281
00282
00283 (*iexp) = 2;
00284 iz = *ibeta;
00285 while (k >= iz) {
00286 iz = iz * (*ibeta);
00287 (*iexp) = (*iexp) + 1;
00288 }
00289 mx = iz + iz - 1;
00290 }
00291
00292
00293
00294
00295
00296
00297 for (;;) {
00298 (*xmin) = y;
00299 y = y * betain;
00300 a = y * one;
00301 tmp = y*t;
00302 tmp1 = a+a;
00303 if ((tmp1 == zero) || (ABS(y) >= (*xmin))) break;
00304 k = k + 1;
00305 tmp1 = tmp*betain;
00306 tmp1 = tmp1*beta;
00307
00308 if ((tmp1 == y) && (tmp != y)) {
00309 nxres = 3;
00310 *xmin = y;
00311 break;
00312 }
00313
00314 }
00315
00316 (*minexp) = -k;
00317
00318
00319
00320
00321
00322 if ((mx <= k+k-3) && ((*ibeta) != 10)) {
00323 mx = mx + mx;
00324 (*iexp) = (*iexp) + 1;
00325 }
00326
00327 (*maxexp) = mx + (*minexp);
00328
00329
00330
00331
00332
00333 (*irnd) = (*irnd)+nxres;
00334
00335
00336
00337
00338
00339 if ((*irnd) >= 2) (*maxexp) = (*maxexp)-2;
00340
00341
00342
00343
00344
00345
00346
00347 i = (*maxexp) + (*minexp);
00348 if (((*ibeta) == 2) && (i == 0)) (*maxexp) = (*maxexp) - 1;
00349 if (i > 20) (*maxexp) = (*maxexp) - 1;
00350 if (a != y) (*maxexp) = (*maxexp) - 2;
00351 (*xmax) = one - (*epsneg);
00352 tmp = (*xmax)*one;
00353 if (tmp != (*xmax)) (*xmax) = one - beta * (*epsneg);
00354 (*xmax) = (*xmax) / (beta * beta * beta * (*xmin));
00355 i = (*maxexp) + (*minexp) + 3;
00356 if (i > 0) {
00357
00358 for (j = 1; j<=i; j++ ) {
00359 if ((*ibeta) == 2) (*xmax) = (*xmax) + (*xmax);
00360 if ((*ibeta) != 2) (*xmax) = (*xmax) * beta;
00361 }
00362
00363 }
00364
00365 return;
00366
00367 }
00368
00369 #ifndef TEST
00370
00371 F77_RET_T
00372 F77_FUNC (machar, MACHAR) (REAL *xmin, REAL *xmax, REAL *epsneg,
00373 REAL *eps, REAL *log10_ibeta)
00374 {
00375 #if defined (_CRAY)
00376
00377
00378
00379 int ibeta = FLT_RADIX;
00380 *xmin = DBL_MIN;
00381 *xmax = DBL_MAX;
00382 *epsneg = DBL_EPSILON;
00383 *eps = DBL_EPSILON;
00384
00385 #else
00386
00387 int ibeta, iexp, irnd, it, machep, maxexp, minexp, negep, ngrd;
00388
00389 rmachar (&ibeta, &it, &irnd, &ngrd, &machep, &negep, &iexp, &minexp,
00390 &maxexp, eps, epsneg, xmin, xmax);
00391 #endif
00392
00393 *log10_ibeta = log10 ((REAL) ibeta);
00394
00395 F77_RETURN (0)
00396 }
00397
00398 #else
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421 int
00422 main (void)
00423 {
00424
00425 int ibeta, iexp, irnd, it, machep, maxexp, minexp, negep, ngrd;
00426
00427 int i;
00428
00429 REAL eps, epsneg, xmax, xmin;
00430
00431 union wjc
00432 {
00433 long int jj[REALSIZE];
00434 REAL xbig;
00435 } uval;
00436
00437 rmachar (&ibeta, &it, &irnd, &ngrd, &machep, &negep, &iexp,
00438 &minexp, &maxexp, &eps, &epsneg, &xmin, &xmax);
00439
00440 printf (PREC);
00441 printf (" precision MACHAR constants\n");
00442 printf ("ibeta = %d\n", ibeta);
00443 printf ("it = %d\n", it);
00444 printf ("irnd = %d\n", irnd);
00445 printf ("ngrd = %d\n", ngrd);
00446 printf ("machep = %d\n", machep);
00447 printf ("negep = %d\n", negep);
00448 printf ("iexp = %d\n", iexp);
00449 printf ("minexp = %d\n", minexp);
00450 printf ("maxexp = %d\n", maxexp);
00451
00452 #define DISPLAY(s, x) \
00453 do \
00454 { \
00455 uval.xbig = x ; \
00456 printf (s); \
00457 printf (" %24.16e ", (double) x) ; \
00458 for (i = 0; i < REALSIZE; i++) \
00459 printf (" %9X ", uval.jj[i]) ; \
00460 printf ("\n"); \
00461 } \
00462 while (0)
00463
00464 DISPLAY ("eps ", eps);
00465 DISPLAY ("epsneg", epsneg);
00466 DISPLAY ("xmin ", xmin);
00467 DISPLAY ("xmax ", xmax);
00468
00469 return 0;
00470 }
00471
00472 #endif