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