]> git.sur5r.net Git - cc65/blob - test/val/cq626.c
remote TABs in doc/ and test/
[cc65] / test / val / cq626.c
1 /*
2   !!DESCRIPTION!! C-Manual Chapter 6.2: Float and double, 6.3 Floating and integral, 6.4 Pointers and integers, 6.5 Unsigned, 6.6 Arithmetic conversions
3   !!ORIGIN!!      LCC 4.1 Testsuite
4   !!LICENCE!!     own, freely distributeable for non-profit. read CPYRIGHT.LCC
5 */
6
7 #include "common.h"
8
9 struct defs {
10      int cbits;          /* No. of bits per char           */
11      int ibits;          /*                 int            */
12      int sbits;          /*                 short          */
13      int lbits;          /*                 long           */
14      int ubits;          /*                 unsigned       */
15      int fbits;          /*                 float          */
16      int dbits;          /*                 double         */
17      #ifndef NO_FLOATS
18         float fprec;        /* Smallest number that can be    */
19         float dprec;        /* significantly added to 1.      */
20      #endif
21      int flgs;           /* Print return codes, by section */
22      int flgm;           /* Announce machine dependencies  */
23      int flgd;           /* give explicit diagnostics      */
24      int flgl;           /* Report local return codes.     */
25      int rrc;            /* recent return code             */
26      int crc;            /* Cumulative return code         */
27      char rfs[8];        /* Return from section            */
28 };
29
30      int lbits;          /*                 long           */
31      int ubits;          /*                 unsigned       */
32      int fbits;          /*                 float          */
33      int dbits;          /*                 double         */
34      #ifndef NO_FLOATS
35         float fprec;        /* Smallest number that can be    */
36         float dprec;        /* significantly added to 1.      */
37      #endif
38      int flgs;           /* Print return codes, by section */
39      int flgm;           /* Announce machine dependencies  */
40      int flgd;           /* give explicit diagnostics      */
41      int flgl;           /* Report local return codes.     */
42      int rrc;            /* recent return code             */
43      int crc;            /* Cumulative return code         */
44      char rfs[8];        /* Return from section            */
45
46 #define CQ26_INCLUDED
47 /*
48   section s26, which pokes around at the hardware
49   trying to figure out the characteristics of the machine that
50   it is running on, saves information that is subsequently
51   used by sections s626, s72, and s757. If this program is
52   to be broken up into smallish pieces, say for running on
53   a microcomputer, take care to see that s26 is called before
54   calling any of the latter three sections.
55 */
56
57 /*
58         2.6  Hardware Characteristics
59 */
60
61 #ifndef NO_OLD_FUNC_DECL
62 s26(pd0)
63 struct defs *pd0;
64 {
65 #else
66 s26(struct defs *pd0) {
67 #endif
68    static char qs26[8] = "s26    ";
69    char *ps, *pt;
70    char c0, c1;
71    #ifndef NO_FLOATS
72         float temp, one, delta;
73         double tempd, oned;
74    #endif
75    static char s[] = "%3d bits in %ss.\n";
76    static char s2[] = "%e is the least number that can be added to 1. (%s).\n";
77
78    ps = qs26;
79    pt = pd0->rfs;
80
81    while(*pt++ = *ps++);
82
83           /* Here, we shake the machinery a little to see what falls
84              out.  First, we find out how many bits are in a char.  */
85
86    pd0->cbits = 0;
87    c0 = 0;
88    c1 = 1;
89
90    while(c0 != c1) {
91      c1 = c1<<1;
92      pd0->cbits = pd0->cbits+1;
93    }
94           /* That information lets us determine the size of everything else. */
95
96    pd0->ibits = pd0->cbits * sizeof(int);
97    pd0->sbits = pd0->cbits * sizeof(short);
98    pd0->lbits = pd0->cbits * sizeof(long);
99    pd0->ubits = pd0->cbits * sizeof(unsigned);
100    #ifndef NO_FLOATS
101         pd0->fbits = pd0->cbits * sizeof(float);
102         pd0->dbits = pd0->cbits * sizeof(double);
103    #endif
104
105           /* We have now almost reconstructed the table in section 2.6, the
106              exception being the range of the floating point hardware.
107              Now there are just so many ways to conjure up a floating point
108              representation system that it's damned near impossible to guess
109              what's going on by writing a program to interpret bit patterns.
110              Further, the information isn't all that useful, if we consider
111              the fact that machines that won't handle numbers between 10**30
112              and 10**-30 are very hard to find, and that people playing with
113              numbers outside that range have a lot more to worry about than
114              just the capacity of the characteristic.
115
116              A much more useful measure is the precision, which can be ex-
117              pressed in terms of the smallest number that can be added to
118              1. without loss of significance. We calculate that here, for
119              float and double.                       */
120
121 #ifndef NO_FLOATS
122    one = 1.;
123    delta = 1.;
124    temp = 0.;
125    while(temp != one) {
126      temp = one+delta;
127      delta = delta/2.;
128    }
129    pd0->fprec = delta * 4.;
130    oned = 1.;
131    delta = 1.;
132    tempd = 0.;
133    while(tempd != oned) {
134      tempd = oned+delta;
135      delta = delta/2.;
136    }
137    pd0->dprec = delta * 4.;
138 #endif
139
140           /* Now, if anyone's interested, we publish the results.       */
141
142 #ifndef CQ26_INCLUDED
143    if(pd0->flgm != 0) {
144      printf(s,pd0->cbits,"char");
145      printf(s,pd0->ibits,"int");
146      printf(s,pd0->sbits,"short");
147      printf(s,pd0->lbits,"long");
148      printf(s,pd0->ubits,"unsigned");
149      printf(s,pd0->fbits,"float");
150      printf(s,pd0->dbits,"double");
151      #ifndef NO_FLOATS
152         printf(s2,pd0->fprec,"float");
153         printf(s2,pd0->dprec,"double");
154      #else
155         printf("NO_FLOATS\n");
156      #endif
157    }
158 #endif
159           /* Since we are only exploring and perhaps reporting, but not
160              testing any features, we cannot return an error code.  */
161
162    return 0;
163 }
164
165 int extvar;
166
167 #ifndef NO_OLD_FUNC_DECL
168 s626(pd0)          /* 6.2 Float and double                  */
169                    /* 6.3 Floating and integral                 */
170                    /* 6.4 Pointers and integers                 */
171                    /* 6.5 Unsigned                              */
172                    /* 6.6 Arithmetic conversions                */
173 struct defs *pd0;
174 {
175 #else
176 int s626(struct defs *pd0){
177 #endif
178    static char s626er[] = "s626,er%d\n";
179    static char qs626[8] = "s626   ";
180    int rc;
181    char *ps, *pt;
182    #ifndef NO_FLOATS
183    float eps, f1, f2, f3, f4, f;
184    #endif
185    long lint1, lint2, l, ls;
186    char c, t[28], t0;
187    short s;
188    int is, i, j;
189    unsigned u, us;
190    #ifndef NO_FLOATS
191         double d, ds;
192    #endif
193    ps = qs626;
194    pt = pd0->rfs;
195    rc = 0;
196    while (*pt++ = *ps++);
197
198    #ifndef NO_FLOATS
199
200         /* Conversions of integral values to floating type are
201         well-behaved.                                           */
202
203    f1 = 1.;
204    lint1 = 1.;
205    lint2 = 1.;
206
207    for(j=0;j<pd0->lbits-2;j++){
208      f1 = f1*2;
209      lint2 = (lint2<<1)|lint1;
210    }
211    f2 = lint2;
212    f1 = (f1-f2)/f1;
213    if(f1>2.*pd0->fprec){
214      rc = rc+2;
215      if(pd0->flgd != 0) printf(s626er,2);
216    }
217
218         /* Pointer-integer combinations are discussed in s74,
219         "Additive operators". The unsigned-int combination
220         appears below.                                          */
221
222    c = 125;
223    s = 125;
224    i = 125;     is = 15625;
225    u = 125;     us = 15625;
226    l = 125;     ls = 15625;
227    f = 125.;
228    d = 125.;    ds = 15625.;
229
230    for(j=0;j<28;j++) t[j] = 0;
231
232    if(c*c != is) t[ 0] = 1;
233    if(s*c != is) t[ 1] = 1;
234    if(s*s != is) t[ 2] = 1;
235    if(i*c != is) t[ 3] = 1;
236    if(i*s != is) t[ 4] = 1;
237    if(i*i != is) t[ 5] = 1;
238    if(u*c != us) t[ 6] = 1;
239    if(u*s != us) t[ 7] = 1;
240    if(u*i != us) t[ 8] = 1;
241    if(u*u != us) t[ 9] = 1;
242    if(l*c != ls) t[10] = 1;
243    if(l*s != ls) t[11] = 1;
244    if(l*i != ls) t[12] = 1;
245    if(l*u != us) t[13] = 1;
246    if(l*l != ls) t[14] = 1;
247    if(f*c != ds) t[15] = 1;
248    if(f*s != ds) t[16] = 1;
249    if(f*i != ds) t[17] = 1;
250    if(f*u != ds) t[18] = 1;
251    if(f*l != ds) t[19] = 1;
252    if(f*f != ds) t[20] = 1;
253    if(d*c != ds) t[21] = 1;
254    if(d*s != ds) t[22] = 1;
255    if(d*i != ds) t[23] = 1;
256    if(d*u != ds) t[24] = 1;
257    if(d*l != ds) t[25] = 1;
258    if(d*f != ds) t[26] = 1;
259    if(d*d != ds) t[27] = 1;
260
261    t0 = 0;
262    for(j=0; j<28; j++) t0 = t0+t[j];
263
264    if(t0 != 0){
265      rc = rc+4;
266      if(pd0->flgd != 0){
267        printf(s626er,4);
268        printf("   key=");
269        for(j=0;j<28;j++) printf("%d",t[j]);
270        printf("\n");
271      }
272    }
273
274    #endif
275
276         /* When an unsigned integer is converted to long,
277            the value of the result is the same numerically
278            as that of the unsigned integer.               */
279
280    l = (unsigned)0100000;
281    if((long)l > (unsigned)0100000){
282       rc = rc+8;
283       if(pd0->flgd != 0) printf(s626er,8);
284    }
285
286    return rc;
287 }
288
289 /*********************************************************************************************
290  the main loop that launches the sections
291 *********************************************************************************************/
292
293 #ifndef NO_TYPELESS_STRUCT_PTR
294         int section(int j,struct* pd0){
295 #else
296         int section(int j,void* pd0){
297 #endif
298         switch(j){
299                 case 0: return s26(pd0);
300                 case 1: return s626(pd0);
301         }
302 }
303
304 #define cq_sections 2
305
306 /*
307         C REFERENCE MANUAL (main)
308 */
309
310 #ifndef NO_OLD_FUNC_DECL
311 main(n,args)
312 int n;
313 char **args;
314 {
315 #else
316 int main(int n,char **args) {
317 #endif
318
319 int j;
320 static struct defs d0, *pd0;
321         
322    d0.flgs = 1;          /* These flags dictate            */
323    d0.flgm = 1;          /*     the verbosity of           */
324    d0.flgd = 1;          /*         the program.           */
325    d0.flgl = 1;
326
327    pd0 = &d0;
328
329    for (j=0; j<cq_sections; j++) {
330      d0.rrc=section(j,pd0);
331      d0.crc=d0.crc+d0.rrc;
332      if(d0.flgs != 0) printf("Section %s returned %d.\n",d0.rfs,d0.rrc);
333    }
334
335    if(d0.crc == 0) printf("\nNo errors detected.\n");
336    else printf("\nFailed.\n");
337
338    return d0.crc;
339 }