]> git.sur5r.net Git - cc65/blob - test/val/cq757.c
Merge pull request #135 from ikorb/patch1
[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 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 #ifndef NO_OLD_FUNC_DECL
164 s757(pd0)          /* 7.5 Shift operators          */
165                    /* 7.6 Relational operators     */
166                    /* 7.7 Equality operator        */
167 struct defs *pd0;
168 {
169 #else
170 int s757(struct defs *pd0){
171 #endif
172    static char s757er[] = "s757,er%d\n";
173    static char qs757[8] = "s757   ";
174    int rc;
175    char *ps, *pt;
176    int t,lrc,k,j,a,b,c,d,x[16],*p;
177    unsigned rs, ls, rt, lt;
178    ps = qs757;
179    pt = pd0->rfs;
180    rc = 0;
181    while (*pt++ = *ps++);
182
183         /* The shift operators << and >> group left-to-right.
184                                                                 */
185
186    t = 40;
187    if(t<<3<<2 != 1280 || t>>3>>2 != 1){
188      rc = rc+1;
189      if(pd0->flgd != 0) printf(s757er,1);
190    }
191
192         /* In the following test, an n-bit unsigned consisting
193         of all 1s is shifted right (resp. left) k bits, 0<=k<n.
194         We expect to find k 0s followed by n-k 1s (resp. n-k 1s
195         followed by k 0s). If not, we complain.
196                                                                 */
197
198    lrc = 0;
199    for(k=0; k<pd0->ubits; k++){
200      rs = 1;
201      ls = rs<<(pd0->ubits-1);
202
203      rt = 0;
204      lt = ~rt>>k;
205      rt = ~rt<<k;
206
207      for(j=0; j<pd0->ubits;j++){
208        if((j<k) != ((rs&rt) == 0) || (j<k) != ((ls&lt) == 0)) lrc = 1;
209        rs = rs<<1;
210        ls = ls>>1;
211      }
212    }
213
214    if(lrc != 0){
215      rc = rc+2;
216      if(pd0->flgd != 0) printf(s757er,2);
217    }
218
219         /* The relational operators group left-to-right, but this
220         fact is not very useful; a<b<c does not mean what it
221         seems to...
222                                                                 */
223
224    a = 3;
225    b = 2;
226    c = 1;
227
228    if((a<b<c) != 1){
229      rc = rc+4;
230      if(pd0->flgd != 0) printf(s757er,4);
231    }
232
233         /* In general, we take note of the fact that if we got this
234         far the relational operators have to be working. We test only
235         that two pointers may be compared; the result depends on
236         the relative locations in the address space of the
237         pointed-to objects.
238                                                                 */
239    if( &x[1] == &x[0] ){
240      rc = rc+8;
241      if(pd0->flgd != 0) printf(s757er,8);
242    }
243
244    if( &x[1] < &x[0] ) if(pd0->flgm != 0)
245      printf("Increasing array elements assigned to decreasing locations\n");
246
247         /* a<b == c<d whenever a<b and c<d have the same
248         truth value.                                            */
249
250    lrc = 0;
251
252    for(j=0;j<16;j++) x[j] = 1;
253    x[1] = 0;
254    x[4] = 0;
255    x[6] = 0;
256    x[7] = 0;
257    x[9] = 0;
258    x[13] = 0;
259
260    for(a=0;a<2;a++)
261      for(b=0;b<2;b++)
262        for(c=0;c<2;c++)
263          for(d=0;d<2;d++)
264            if((a<b==c<d) != x[8*a+4*b+2*c+d] ) lrc = 1;
265
266    if(lrc != 0){
267      rc = rc+16;
268      if(pd0->flgd != 0) printf(s757er,16);
269    }
270
271         /* A pointer to which zero has been assigned will
272         appear to be equal to zero.
273                                                                 */
274
275    p = 0;
276
277    if(p != 0){
278      rc = rc+32;
279      if(pd0->flgd != 0) printf(s757er,32);
280    }
281
282    return rc;
283 }
284
285 /*********************************************************************************************
286  the main loop that launches the sections
287 *********************************************************************************************/
288
289 #ifndef NO_TYPELESS_STRUCT_PTR
290         int section(int j,struct* pd0){
291 #else
292         int section(int j,void* pd0){
293 #endif
294         switch(j){
295                 case 0: return s26(pd0);
296                 case 1: return s757(pd0);
297         }
298 }
299
300 #define cq_sections 2
301
302 /*
303         C REFERENCE MANUAL (main)
304 */
305
306 #ifndef NO_OLD_FUNC_DECL
307 main(n,args)
308 int n;
309 char **args;
310 {
311 #else
312 int main(int n,char **args) {
313 #endif
314
315 int j;
316 static struct defs d0, *pd0;
317
318    d0.flgs = 1;          /* These flags dictate            */
319    d0.flgm = 1;          /*     the verbosity of           */
320    d0.flgd = 1;          /*         the program.           */
321    d0.flgl = 1;
322
323    pd0 = &d0;
324
325    for (j=0; j<cq_sections; j++) {
326      d0.rrc=section(j,pd0);
327      d0.crc=d0.crc+d0.rrc;
328      if(d0.flgs != 0) printf("Section %s returned %d.\n",d0.rfs,d0.rrc);
329    }
330
331    if(d0.crc == 0) printf("\nNo errors detected.\n");
332    else printf("\nFailed.\n");
333
334    return d0.crc;
335 }