~ubuntu-branches/ubuntu/oneiric/9base/oneiric

« back to all changes in this revision

Viewing changes to lib9/testfltfmt.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2009-08-20 17:34:06 UTC
  • mfrom: (6.2.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090820173406-xpwqa9ruyevvc0ut
Tags: 1:3-3
* Updating maintainer field.
* Updating vcs fields.
* Updating package to standards version 3.8.3.
* Updatin variables writing in rules to consistent style.

Show diffs side-by-side

added added

removed removed

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