]> git.sur5r.net Git - cc65/blob - test/val/cq26.c
42527e80f5e246e84a63931bf8e388e5fd8a25c7
[cc65] / test / val / cq26.c
1 /*
2   !!DESCRIPTION!! C-Manual Chapter 2.6: Hardware Characteristics
3   !!ORIGIN!!      LCC 4.1 Testsuite
4   !!LICENCE!!     own, freely distributeable for non-profit. read CPYRIGHT.LCC
5 */
6
7 #ifndef CQ26_INCLUDED
8 struct defs {
9      int cbits;          /* No. of bits per char           */
10      int ibits;          /*                 int            */
11      int sbits;          /*                 short          */
12      int lbits;          /*                 long           */
13      int ubits;          /*                 unsigned       */
14      int fbits;          /*                 float          */
15      int dbits;          /*                 double         */
16      #ifndef NO_FLOATS
17         float fprec;        /* Smallest number that can be    */
18         float dprec;        /* significantly added to 1.      */
19      #endif
20      int flgs;           /* Print return codes, by section */
21      int flgm;           /* Announce machine dependencies  */
22      int flgd;           /* give explicit diagnostics      */
23      int flgl;           /* Report local return codes.     */
24      int rrc;            /* recent return code             */
25      int crc;            /* Cumulative return code         */
26      char rfs[8];        /* Return from section            */
27 };
28
29      int lbits;          /*                 long           */
30      int ubits;          /*                 unsigned       */
31      int fbits;          /*                 float          */
32      int dbits;          /*                 double         */
33      #ifndef NO_FLOATS
34         float fprec;        /* Smallest number that can be    */
35         float dprec;        /* significantly added to 1.      */
36      #endif
37      int flgs;           /* Print return codes, by section */
38      int flgm;           /* Announce machine dependencies  */
39      int flgd;           /* give explicit diagnostics      */
40      int flgl;           /* Report local return codes.     */
41      int rrc;            /* recent return code             */
42      int crc;            /* Cumulative return code         */
43      char rfs[8];        /* Return from section            */
44
45 #endif
46
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 CQ26_INCLUDED
166
167 /*********************************************************************************************
168  the main loop that launches the sections
169 *********************************************************************************************/
170
171 #ifndef NO_TYPELESS_STRUCT_PTR
172         int section(int j,struct* pd0){
173 #else
174         int section(int j,void* pd0){
175 #endif
176         switch(j){
177                 case 0: return s26(pd0);
178         }
179 }
180
181 #define cq_sections 1
182
183 /*
184         C REFERENCE MANUAL (main)
185 */
186
187 #ifndef NO_OLD_FUNC_DECL
188 main(n,args)
189 int n;
190 char **args;
191 {
192 #else
193 int main(int n,char **args) {
194 #endif
195
196 int j;
197 static struct defs d0, *pd0;
198         
199    d0.flgs = 1;          /* These flags dictate            */
200    d0.flgm = 1;          /*     the verbosity of           */
201    d0.flgd = 1;          /*         the program.           */
202    d0.flgl = 1;
203
204    pd0 = &d0;
205
206    for (j=0; j<cq_sections; j++) {
207      d0.rrc=section(j,pd0);
208      d0.crc=d0.crc+d0.rrc;
209      if(d0.flgs != 0) printf("Section %s returned %d.\n",d0.rfs,d0.rrc);
210    }
211
212    if(d0.crc == 0) printf("\nNo errors detected.\n");
213    else printf("\nFailed.\n");
214
215    return d0.crc;
216 }
217 #endif