Blame


1 85231fd8 2006-05-21 devnull #include <u.h>
2 85231fd8 2006-05-21 devnull #include <libc.h>
3 85231fd8 2006-05-21 devnull #include <stdio.h>
4 85231fd8 2006-05-21 devnull
5 85231fd8 2006-05-21 devnull /*
6 85231fd8 2006-05-21 devnull * try all combination of flags and float conversions
7 85231fd8 2006-05-21 devnull * with some different widths & precisions
8 85231fd8 2006-05-21 devnull */
9 85231fd8 2006-05-21 devnull
10 85231fd8 2006-05-21 devnull #define Njust 2
11 85231fd8 2006-05-21 devnull #define Nplus 3
12 85231fd8 2006-05-21 devnull #define Nalt 2
13 85231fd8 2006-05-21 devnull #define Nzero 2
14 85231fd8 2006-05-21 devnull #define Nspec 5
15 85231fd8 2006-05-21 devnull #define Nwidth 5
16 85231fd8 2006-05-21 devnull #define Nprec 5
17 85231fd8 2006-05-21 devnull
18 85231fd8 2006-05-21 devnull static double fmtvals[] = {
19 85231fd8 2006-05-21 devnull 3.1415925535897932e15,
20 85231fd8 2006-05-21 devnull 3.1415925535897932e14,
21 85231fd8 2006-05-21 devnull 3.1415925535897932e13,
22 85231fd8 2006-05-21 devnull 3.1415925535897932e12,
23 85231fd8 2006-05-21 devnull 3.1415925535897932e11,
24 85231fd8 2006-05-21 devnull 3.1415925535897932e10,
25 85231fd8 2006-05-21 devnull 3.1415925535897932e9,
26 85231fd8 2006-05-21 devnull 3.1415925535897932e8,
27 85231fd8 2006-05-21 devnull 3.1415925535897932e7,
28 85231fd8 2006-05-21 devnull 3.1415925535897932e6,
29 85231fd8 2006-05-21 devnull 3.1415925535897932e5,
30 85231fd8 2006-05-21 devnull 3.1415925535897932e4,
31 85231fd8 2006-05-21 devnull 3.1415925535897932e3,
32 85231fd8 2006-05-21 devnull 3.1415925535897932e2,
33 85231fd8 2006-05-21 devnull 3.1415925535897932e1,
34 85231fd8 2006-05-21 devnull 3.1415925535897932e0,
35 85231fd8 2006-05-21 devnull 3.1415925535897932e-1,
36 85231fd8 2006-05-21 devnull 3.1415925535897932e-2,
37 85231fd8 2006-05-21 devnull 3.1415925535897932e-3,
38 85231fd8 2006-05-21 devnull 3.1415925535897932e-4,
39 85231fd8 2006-05-21 devnull 3.1415925535897932e-5,
40 85231fd8 2006-05-21 devnull 3.1415925535897932e-6,
41 85231fd8 2006-05-21 devnull 3.1415925535897932e-7,
42 85231fd8 2006-05-21 devnull 3.1415925535897932e-8,
43 85231fd8 2006-05-21 devnull 3.1415925535897932e-9,
44 85231fd8 2006-05-21 devnull 3.1415925535897932e-10,
45 85231fd8 2006-05-21 devnull 3.1415925535897932e-11,
46 85231fd8 2006-05-21 devnull 3.1415925535897932e-12,
47 85231fd8 2006-05-21 devnull 3.1415925535897932e-13,
48 85231fd8 2006-05-21 devnull 3.1415925535897932e-14,
49 85231fd8 2006-05-21 devnull 3.1415925535897932e-15,
50 85231fd8 2006-05-21 devnull };
51 85231fd8 2006-05-21 devnull
52 85231fd8 2006-05-21 devnull /*
53 85231fd8 2006-05-21 devnull * are the numbers close?
54 85231fd8 2006-05-21 devnull * used to compare long numbers where the last few digits are garbage
55 85231fd8 2006-05-21 devnull * due to precision problems
56 85231fd8 2006-05-21 devnull */
57 85231fd8 2006-05-21 devnull static int
58 85231fd8 2006-05-21 devnull numclose(char *num1, char *num2)
59 85231fd8 2006-05-21 devnull {
60 85231fd8 2006-05-21 devnull int ndig;
61 4b65e43c 2006-05-22 devnull double d1, d2;
62 85231fd8 2006-05-21 devnull enum { MAXDIG = 15 };
63 85231fd8 2006-05-21 devnull
64 4b65e43c 2006-05-22 devnull d1 = fmtstrtod(num1, 0);
65 4b65e43c 2006-05-22 devnull d2 = fmtstrtod(num2, 0);
66 4b65e43c 2006-05-22 devnull if(d1 != d2)
67 4b65e43c 2006-05-22 devnull return 0;
68 4b65e43c 2006-05-22 devnull
69 85231fd8 2006-05-21 devnull ndig = 0;
70 85231fd8 2006-05-21 devnull while (*num1) {
71 85231fd8 2006-05-21 devnull if (*num1 >= '0' && *num1 <= '9') {
72 85231fd8 2006-05-21 devnull ndig++;
73 85231fd8 2006-05-21 devnull if (ndig > MAXDIG) {
74 85231fd8 2006-05-21 devnull if (!(*num2 >= '0' && *num2 <= '9')) {
75 85231fd8 2006-05-21 devnull return 0;
76 85231fd8 2006-05-21 devnull }
77 85231fd8 2006-05-21 devnull } else if (*num1 != *num2) {
78 85231fd8 2006-05-21 devnull return 0;
79 85231fd8 2006-05-21 devnull }
80 85231fd8 2006-05-21 devnull } else if (*num1 != *num2) {
81 85231fd8 2006-05-21 devnull return 0;
82 85231fd8 2006-05-21 devnull } else if (*num1 == 'e' || *num1 == 'E') {
83 85231fd8 2006-05-21 devnull ndig = 0;
84 85231fd8 2006-05-21 devnull }
85 85231fd8 2006-05-21 devnull num1++;
86 85231fd8 2006-05-21 devnull num2++;
87 85231fd8 2006-05-21 devnull }
88 85231fd8 2006-05-21 devnull if (*num1 || !num2)
89 85231fd8 2006-05-21 devnull return 0;
90 85231fd8 2006-05-21 devnull return 1;
91 85231fd8 2006-05-21 devnull }
92 85231fd8 2006-05-21 devnull
93 85231fd8 2006-05-21 devnull static void
94 85231fd8 2006-05-21 devnull doit(int just, int plus, int alt, int zero, int width, int prec, int spec)
95 85231fd8 2006-05-21 devnull {
96 85231fd8 2006-05-21 devnull char format[256];
97 85231fd8 2006-05-21 devnull char *p;
98 85231fd8 2006-05-21 devnull const char *s;
99 85231fd8 2006-05-21 devnull int i;
100 85231fd8 2006-05-21 devnull
101 85231fd8 2006-05-21 devnull p = format;
102 85231fd8 2006-05-21 devnull *p++ = '%';
103 85231fd8 2006-05-21 devnull if (just > 0)
104 85231fd8 2006-05-21 devnull *p++ = "-"[just - 1];
105 85231fd8 2006-05-21 devnull if (plus > 0)
106 85231fd8 2006-05-21 devnull *p++ = "+ "[plus - 1];
107 85231fd8 2006-05-21 devnull if (alt > 0)
108 85231fd8 2006-05-21 devnull *p++ = "#"[alt - 1];
109 85231fd8 2006-05-21 devnull if (zero > 0)
110 85231fd8 2006-05-21 devnull *p++ = "0"[zero - 1];
111 85231fd8 2006-05-21 devnull
112 85231fd8 2006-05-21 devnull s = "";
113 85231fd8 2006-05-21 devnull switch (width) {
114 85231fd8 2006-05-21 devnull case 1: s = "1"; break;
115 85231fd8 2006-05-21 devnull case 2: s = "5"; break;
116 85231fd8 2006-05-21 devnull case 3: s = "10"; break;
117 85231fd8 2006-05-21 devnull case 4: s = "15"; break;
118 85231fd8 2006-05-21 devnull }
119 85231fd8 2006-05-21 devnull strcpy(p, s);
120 85231fd8 2006-05-21 devnull
121 85231fd8 2006-05-21 devnull s = "";
122 85231fd8 2006-05-21 devnull switch (prec) {
123 85231fd8 2006-05-21 devnull case 1: s = ".0"; break;
124 85231fd8 2006-05-21 devnull case 2: s = ".2"; break;
125 85231fd8 2006-05-21 devnull case 3: s = ".5"; break;
126 85231fd8 2006-05-21 devnull case 4: s = ".15"; break;
127 85231fd8 2006-05-21 devnull }
128 85231fd8 2006-05-21 devnull strcat(p, s);
129 85231fd8 2006-05-21 devnull
130 85231fd8 2006-05-21 devnull p = strchr(p, '\0');
131 85231fd8 2006-05-21 devnull *p++ = "efgEG"[spec];
132 85231fd8 2006-05-21 devnull *p = '\0';
133 85231fd8 2006-05-21 devnull
134 85231fd8 2006-05-21 devnull for (i = 0; i < sizeof(fmtvals) / sizeof(fmtvals[0]); i++) {
135 4b65e43c 2006-05-22 devnull char ref[1024], buf[1024];
136 4b65e43c 2006-05-22 devnull Rune rbuf[1024];
137 4b65e43c 2006-05-22 devnull double d1, d2;
138 85231fd8 2006-05-21 devnull
139 85231fd8 2006-05-21 devnull sprintf(ref, format, fmtvals[i]);
140 85231fd8 2006-05-21 devnull snprint(buf, sizeof(buf), format, fmtvals[i]);
141 85231fd8 2006-05-21 devnull if (strcmp(ref, buf) != 0
142 85231fd8 2006-05-21 devnull && !numclose(ref, buf)) {
143 4b65e43c 2006-05-22 devnull d1 = fmtstrtod(ref, 0);
144 4b65e43c 2006-05-22 devnull d2 = fmtstrtod(buf, 0);
145 fa325e9b 2020-01-10 cross fprintf(stderr, "%s: ref='%s'%s fmt='%s'%s\n",
146 fa325e9b 2020-01-10 cross format,
147 fa325e9b 2020-01-10 cross ref, d1==fmtvals[i] ? "" : " (ref is inexact!)",
148 4b65e43c 2006-05-22 devnull buf, d2==fmtvals[i] ? "" : " (fmt is inexact!)");
149 4b65e43c 2006-05-22 devnull // exits("oops");
150 85231fd8 2006-05-21 devnull }
151 85231fd8 2006-05-21 devnull
152 85231fd8 2006-05-21 devnull /* Check again with output to rune string */
153 4b65e43c 2006-05-22 devnull runesnprint(rbuf, 1024, format, fmtvals[i]);
154 85231fd8 2006-05-21 devnull snprint(buf, sizeof(buf), "%S", rbuf);
155 85231fd8 2006-05-21 devnull if (strcmp(ref, buf) != 0
156 85231fd8 2006-05-21 devnull && !numclose(ref, buf)) {
157 4b65e43c 2006-05-22 devnull d1 = fmtstrtod(ref, 0);
158 4b65e43c 2006-05-22 devnull d2 = fmtstrtod(buf, 0);
159 fa325e9b 2020-01-10 cross fprintf(stderr, "%s: ref='%s'%s fmt='%s'%s\n",
160 fa325e9b 2020-01-10 cross format,
161 fa325e9b 2020-01-10 cross ref, d1==fmtvals[i] ? "" : " (ref is inexact!)",
162 4b65e43c 2006-05-22 devnull buf, d2==fmtvals[i] ? "" : " (fmt is inexact!)");
163 4b65e43c 2006-05-22 devnull // exits("oops");
164 85231fd8 2006-05-21 devnull }
165 85231fd8 2006-05-21 devnull }
166 85231fd8 2006-05-21 devnull }
167 85231fd8 2006-05-21 devnull
168 85231fd8 2006-05-21 devnull void
169 85231fd8 2006-05-21 devnull main(int argc, char **argv)
170 85231fd8 2006-05-21 devnull {
171 85231fd8 2006-05-21 devnull int just, plus, alt, zero, width, prec, spec;
172 85231fd8 2006-05-21 devnull
173 85231fd8 2006-05-21 devnull for (just = 0; just < Njust; just++)
174 85231fd8 2006-05-21 devnull for (plus = 0; plus < Nplus; plus++)
175 85231fd8 2006-05-21 devnull for (alt = 0; alt < Nalt; alt++)
176 85231fd8 2006-05-21 devnull for (zero = 0; zero < Nzero; zero++)
177 85231fd8 2006-05-21 devnull for (width = 0; width < Nwidth; width++)
178 85231fd8 2006-05-21 devnull for (prec = 0; prec < Nprec; prec++)
179 85231fd8 2006-05-21 devnull for (spec = 0; spec < Nspec; spec++)
180 85231fd8 2006-05-21 devnull doit(just, plus, alt, zero, width, prec, spec);
181 85231fd8 2006-05-21 devnull
182 85231fd8 2006-05-21 devnull exits(0);
183 85231fd8 2006-05-21 devnull }