arithchk.c
Go to the documentation of this file.
00001 /****************************************************************
00002 Copyright (C) 1997, 1998, 2000 Lucent Technologies
00003 All Rights Reserved
00004 
00005 Permission to use, copy, modify, and distribute this software and
00006 its documentation for any purpose and without fee is hereby
00007 granted, provided that the above copyright notice appear in all
00008 copies and that both that the copyright notice and this
00009 permission notice and warranty disclaimer appear in supporting
00010 documentation, and that the name of Lucent or any of its entities
00011 not be used in advertising or publicity pertaining to
00012 distribution of the software without specific, written prior
00013 permission.
00014 
00015 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
00016 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
00017 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
00018 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00019 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
00020 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
00021 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
00022 THIS SOFTWARE.
00023 ****************************************************************/
00024 
00025 /* Try to deduce arith.h from arithmetic properties. */
00026 
00027 #include <stdio.h>
00028 #include <math.h>
00029 #include <errno.h>
00030 
00031 #ifdef NO_FPINIT
00032 #define fpinit_ASL()
00033 #else
00034 #ifndef KR_headers
00035 extern
00036 #ifdef __cplusplus
00037         "C"
00038 #endif
00039         void fpinit_ASL(void);
00040 #endif /*KR_headers*/
00041 #endif /*NO_FPINIT*/
00042 
00043  static int dalign;
00044  typedef struct
00045 Akind {
00046         char *name;
00047         int   kind;
00048         } Akind;
00049 
00050  static Akind
00051 IEEE_8087       = { "IEEE_8087", 1 },
00052 IEEE_MC68k      = { "IEEE_MC68k", 2 },
00053 IBM             = { "IBM", 3 },
00054 VAX             = { "VAX", 4 },
00055 CRAY            = { "CRAY", 5};
00056 
00057  static double t_nan;
00058 
00059  static Akind *
00060 Lcheck(void)
00061 {
00062         union {
00063                 double d;
00064                 long L[2];
00065                 } u;
00066         struct {
00067                 double d;
00068                 long L;
00069                 } x[2];
00070 
00071         if (sizeof(x) > 2*(sizeof(double) + sizeof(long)))
00072                 dalign = 1;
00073         u.L[0] = u.L[1] = 0;
00074         u.d = 1e13;
00075         if (u.L[0] == 1117925532 && u.L[1] == -448790528)
00076                 return &IEEE_MC68k;
00077         if (u.L[1] == 1117925532 && u.L[0] == -448790528)
00078                 return &IEEE_8087;
00079         if (u.L[0] == -2065213935 && u.L[1] == 10752)
00080                 return &VAX;
00081         if (u.L[0] == 1267827943 && u.L[1] == 704643072)
00082                 return &IBM;
00083         return 0;
00084         }
00085 
00086  static Akind *
00087 icheck(void)
00088 {
00089         union {
00090                 double d;
00091                 int L[2];
00092                 } u;
00093         struct {
00094                 double d;
00095                 int L;
00096                 } x[2];
00097 
00098         if (sizeof(x) > 2*(sizeof(double) + sizeof(int)))
00099                 dalign = 1;
00100         u.L[0] = u.L[1] = 0;
00101         u.d = 1e13;
00102         if (u.L[0] == 1117925532 && u.L[1] == -448790528)
00103                 return &IEEE_MC68k;
00104         if (u.L[1] == 1117925532 && u.L[0] == -448790528)
00105                 return &IEEE_8087;
00106         if (u.L[0] == -2065213935 && u.L[1] == 10752)
00107                 return &VAX;
00108         if (u.L[0] == 1267827943 && u.L[1] == 704643072)
00109                 return &IBM;
00110         return 0;
00111         }
00112 
00113 char *emptyfmt = "";    /* avoid possible warning message with printf("") */
00114 
00115  static Akind *
00116 ccheck(void)
00117 {
00118         union {
00119                 double d;
00120                 long L;
00121                 } u;
00122         long Cray1;
00123 
00124         /* Cray1 = 4617762693716115456 -- without overflow on non-Crays */
00125         Cray1 = printf(emptyfmt) < 0 ? 0 : 4617762;
00126         if (printf(emptyfmt, Cray1) >= 0)
00127                 Cray1 = 1000000*Cray1 + 693716;
00128         if (printf(emptyfmt, Cray1) >= 0)
00129                 Cray1 = 1000000*Cray1 + 115456;
00130         u.d = 1e13;
00131         if (u.L == Cray1)
00132                 return &CRAY;
00133         return 0;
00134         }
00135 
00136  static int
00137 fzcheck(void)
00138 {
00139         double a, b;
00140         int i;
00141 
00142         a = 1.;
00143         b = .1;
00144         for(i = 155;; b *= b, i >>= 1) {
00145                 if (i & 1) {
00146                         a *= b;
00147                         if (i == 1)
00148                                 break;
00149                         }
00150                 }
00151         b = a * a;
00152         return b == 0.;
00153         }
00154 
00155  static int
00156 need_nancheck(void)
00157 {
00158         double t;
00159 
00160         errno = 0;
00161         t = log(t_nan);
00162         if (errno == 0)
00163                 return 1;
00164         errno = 0;
00165         t = sqrt(t_nan);
00166         return errno == 0;
00167         }
00168 
00169  void
00170 get_nanbits(unsigned int *b, int k)
00171 {
00172         union { double d; unsigned int z[2]; } u, u1, u2;
00173 
00174         k = 2 - k;
00175         u1.z[k] = u2.z[k] = 0x7ff00000;
00176         u1.z[1-k] = u2.z[1-k] = 0;
00177         u.d = u1.d - u2.d;      /* Infinity - Infinity */
00178         b[0] = u.z[0];
00179         b[1] = u.z[1];
00180         }
00181 
00182  int
00183 main(void)
00184 {
00185         FILE *f;
00186         Akind *a = 0;
00187         int Ldef = 0;
00188         unsigned int nanbits[2];
00189 
00190         fpinit_ASL();
00191 #ifdef WRITE_ARITH_H    /* for Symantec's buggy "make" */
00192         f = fopen("arith.h", "w");
00193         if (!f) {
00194                 printf("Cannot open arith.h\n");
00195                 return 1;
00196                 }
00197 #else
00198         f = stdout;
00199 #endif
00200 
00201         if (sizeof(double) == 2*sizeof(long))
00202                 a = Lcheck();
00203         else if (sizeof(double) == 2*sizeof(int)) {
00204                 Ldef = 1;
00205                 a = icheck();
00206                 }
00207         else if (sizeof(double) == sizeof(long))
00208                 a = ccheck();
00209         if (a) {
00210                 fprintf(f, "#define %s\n#define Arith_Kind_ASL %d\n",
00211                         a->name, a->kind);
00212                 if (Ldef)
00213                         fprintf(f, "#define Long int\n#define Intcast (int)(long)\n");
00214                 if (dalign)
00215                         fprintf(f, "#define Double_Align\n");
00216                 if (sizeof(char*) == 8)
00217                         fprintf(f, "#define X64_bit_pointers\n");
00218 #ifndef NO_LONG_LONG
00219                 if (sizeof(long long) < 8)
00220 #endif
00221                         fprintf(f, "#define NO_LONG_LONG\n");
00222                 if (a->kind <= 2) {
00223                         if (fzcheck())
00224                                 fprintf(f, "#define Sudden_Underflow\n");
00225                         t_nan = -a->kind;
00226                         if (need_nancheck())
00227                                 fprintf(f, "#define NANCHECK\n");
00228                         if (sizeof(double) == 2*sizeof(unsigned int)) {
00229                                 get_nanbits(nanbits, a->kind);
00230                                 fprintf(f, "#define QNaN0 0x%x\n", nanbits[0]);
00231                                 fprintf(f, "#define QNaN1 0x%x\n", nanbits[1]);
00232                                 }
00233                         }
00234                 return 0;
00235                 }
00236         fprintf(f, "/* Unknown arithmetic */\n");
00237         return 1;
00238         }
00239 
00240 #ifdef __sun
00241 #ifdef __i386
00242 /* kludge for Intel Solaris */
00243 void fpsetprec(int x) { }
00244 #endif
00245 #endif


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:55:14