]> git.sur5r.net Git - cc65/blob - test/val/cq757.c
60b588555fa55a724cfb67fdc1ce1dd6c7f4d4f1
[cc65] / test / val / cq757.c
1 /*
2   !!DESCRIPTION!! C-Manual Chapter 7.5: Shift operators, 7.6 Relational operators, 7.7 Equality operator
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 #ifndef NO_OLD_FUNC_DECL
166 s757(pd0)          /* 7.5 Shift operators          */
167                    /* 7.6 Relational operators     */
168                    /* 7.7 Equality operator        */
169 struct defs *pd0;
170 {
171 #else
172 int s757(struct defs *pd0){
173 #endif
174    static char s757er[] = "s757,er%d\n";
175    static char qs757[8] = "s757   ";
176    int rc;
177    char *ps, *pt;
178    int t,lrc,k,j,a,b,c,d,x[16],*p;
179    unsigned rs, ls, rt, lt;
180    ps = qs757;
181    pt = pd0->rfs;
182    rc = 0;
183    while (*pt++ = *ps++);
184
185         /* The shift operators << and >> group left-to-right.
186                                                                 */
187
188    t = 40;
189    if(t<<3<<2 != 1280 || t>>3>>2 != 1){
190      rc = rc+1;
191      if(pd0->flgd != 0) printf(s757er,1);
192    }
193
194         /* In the following test, an n-bit unsigned consisting
195         of all 1s is shifted right (resp. left) k bits, 0<=k<n.
196         We expect to find k 0s followed by n-k 1s (resp. n-k 1s
197         followed by k 0s). If not, we complain.
198                                                                 */
199
200    lrc = 0;
201    for(k=0; k<pd0->ubits; k++){
202      rs = 1;
203      ls = rs<<(pd0->ubits-1);
204
205      rt = 0;
206      lt = ~rt>>k;
207      rt = ~rt<<k;
208
209      for(j=0; j<pd0->ubits;j++){
210        if((j<k) != ((rs&rt) == 0) || (j<k) != ((ls&lt) == 0)) lrc = 1;
211        rs = rs<<1;
212        ls = ls>>1;
213      }
214    }
215
216    if(lrc != 0){
217      rc = rc+2;
218      if(pd0->flgd != 0) printf(s757er,2);
219    }
220
221         /* The relational operators group left-to-right, but this
222         fact is not very useful; a<b<c does not mean what it
223         seems to...
224                                                                 */
225
226    a = 3;
227    b = 2;
228    c = 1;
229
230    if((a<b<c) != 1){
231      rc = rc+4;
232      if(pd0->flgd != 0) printf(s757er,4);
233    }
234
235         /* In general, we take note of the fact that if we got this
236         far the relational operators have to be working. We test only
237         that two pointers may be compared; the result depends on
238         the relative locations in the address space of the
239         pointed-to objects.
240                                                                 */
241    if( &x[1] == &x[0] ){
242      rc = rc+8;
243      if(pd0->flgd != 0) printf(s757er,8);
244    }
245
246    if( &x[1] < &x[0] ) if(pd0->flgm != 0)
247      printf("Increasing array elements assigned to decreasing locations\n");
248
249         /* a<b == c<d whenever a<b and c<d have the same
250         truth value.                                            */
251
252    lrc = 0;
253
254    for(j=0;j<16;j++) x[j] = 1;
255    x[1] = 0;
256    x[4] = 0;
257    x[6] = 0;
258    x[7] = 0;
259    x[9] = 0;
260    x[13] = 0;
261
262    for(a=0;a<2;a++)
263      for(b=0;b<2;b++)
264        for(c=0;c<2;c++)
265          for(d=0;d<2;d++)
266            if((a<b==c<d) != x[8*a+4*b+2*c+d] ) lrc = 1;
267
268    if(lrc != 0){
269      rc = rc+16;
270      if(pd0->flgd != 0) printf(s757er,16);
271    }
272
273         /* A pointer to which zero has been assigned will
274         appear to be equal to zero.
275                                                                 */
276
277    p = 0;
278
279    if(p != 0){
280      rc = rc+32;
281      if(pd0->flgd != 0) printf(s757er,32);
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 s757(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 }