Qtest.c revision 1.2 1 1.1 christos /****************************************************************
2 1.1 christos
3 1.1 christos The author of this software is David M. Gay.
4 1.1 christos
5 1.1 christos Copyright (C) 1998-2001 by Lucent Technologies
6 1.1 christos All Rights Reserved
7 1.1 christos
8 1.1 christos Permission to use, copy, modify, and distribute this software and
9 1.1 christos its documentation for any purpose and without fee is hereby
10 1.1 christos granted, provided that the above copyright notice appear in all
11 1.1 christos copies and that both that the copyright notice and this
12 1.1 christos permission notice and warranty disclaimer appear in supporting
13 1.1 christos documentation, and that the name of Lucent or any of its entities
14 1.1 christos not be used in advertising or publicity pertaining to
15 1.1 christos distribution of the software without specific, written prior
16 1.1 christos permission.
17 1.1 christos
18 1.1 christos LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19 1.1 christos INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
20 1.1 christos IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
21 1.1 christos SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22 1.1 christos WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
23 1.1 christos IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
24 1.1 christos ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
25 1.1 christos THIS SOFTWARE.
26 1.1 christos
27 1.1 christos ****************************************************************/
28 1.1 christos
29 1.1 christos /* Please send bug reports to David M. Gay (dmg at acm dot org,
30 1.1 christos * with " at " changed at "@" and " dot " changed to "."). */
31 1.1 christos
32 1.1 christos /* Test program for g_Qfmt, strtoIQ, strtopQ, and strtorQ.
33 1.1 christos *
34 1.1 christos * Inputs (on stdin):
35 1.1 christos * r rounding_mode
36 1.1 christos * n ndig
37 1.1 christos * number
38 1.1 christos * #hex0 hex1 hex2 hex3
39 1.1 christos *
40 1.1 christos * rounding_mode values:
41 1.1 christos * 0 = toward zero
42 1.1 christos * 1 = nearest
43 1.1 christos * 2 = toward +Infinity
44 1.1 christos * 3 = toward -Infinity
45 1.1 christos *
46 1.1 christos * where number is a decimal floating-point number,
47 1.1 christos * hex0 is a string of <= 8 Hex digits for the most significant
48 1.1 christos * word of the number, hex1 is a similar string for the next
49 1.1 christos * word, etc., and ndig is a parameters to g_Qfmt.
50 1.1 christos */
51 1.1 christos
52 1.1 christos #include "gdtoa.h"
53 1.1 christos #include <stdio.h>
54 1.1 christos #include <stdlib.h>
55 1.1 christos #include <string.h>
56 1.1 christos
57 1.1 christos extern int getround ANSI((int,char*));
58 1.1 christos
59 1.1 christos static char ibuf[2048], obuf[2048];
60 1.1 christos #undef _0
61 1.1 christos #undef _1
62 1.1 christos
63 1.2 christos /* one or the other of IEEE_BIG_ENDIAN or IEEE_LITTLE_ENDIAN should be #defined */
64 1.1 christos
65 1.2 christos #ifdef IEEE_BIG_ENDIAN
66 1.1 christos #define _0 0
67 1.1 christos #define _1 1
68 1.1 christos #define _2 2
69 1.1 christos #define _3 3
70 1.1 christos #endif
71 1.2 christos #ifdef IEEE_LITTLE_ENDIAN
72 1.1 christos #define _0 3
73 1.1 christos #define _1 2
74 1.1 christos #define _2 1
75 1.1 christos #define _3 0
76 1.1 christos #endif
77 1.1 christos
78 1.1 christos #define U (unsigned long)
79 1.1 christos
80 1.1 christos int
81 1.1 christos main(Void)
82 1.1 christos {
83 1.1 christos char *s, *s1, *se, *se1;
84 1.1 christos int Ltest, i, dItry, ndig = 0, r = 1;
85 1.1 christos union { long double d; ULong bits[4]; } u, v[2], w;
86 1.1 christos
87 1.1 christos w.bits[0] = w.bits[3] = 0;
88 1.1 christos w.d = 1.;
89 1.1 christos u.d = 3.;
90 1.1 christos w.d = w.d / u.d;
91 1.1 christos Ltest = sizeof(long double) == 16 && w.bits[0] && w.bits[3];
92 1.1 christos while( (s = fgets(ibuf, sizeof(ibuf), stdin)) !=0) {
93 1.1 christos while(*s <= ' ')
94 1.1 christos if (!*s++)
95 1.1 christos continue;
96 1.1 christos dItry = 0;
97 1.1 christos switch(*s) {
98 1.1 christos case 'r':
99 1.1 christos r = getround(r, s);
100 1.1 christos continue;
101 1.1 christos case 'n':
102 1.1 christos i = s[1];
103 1.1 christos if (i <= ' ' || (i >= '0' && i <= '9')) {
104 1.1 christos ndig = atoi(s+1);
105 1.1 christos continue;
106 1.1 christos }
107 1.1 christos break; /* nan? */
108 1.1 christos case '#':
109 1.1 christos /* sscanf(s+1, "%lx %lx %lx %lx", &u.bits[_0], */
110 1.1 christos /* &u.bits[_1], &u.bits[_2], &u.bits[_3]); */
111 1.1 christos u.bits[_0] = (ULong)strtoul(s1 = s+1, &se, 16);
112 1.1 christos if (se > s1) {
113 1.1 christos u.bits[_1] = (ULong)strtoul(s1 = se, &se, 16);
114 1.1 christos if (se > s1) {
115 1.1 christos u.bits[_2] = (ULong)strtoul(s1 = se, &se, 16);
116 1.1 christos if (se > s1)
117 1.1 christos u.bits[_3] = (ULong)strtoul(s1 = se, &se, 16);
118 1.1 christos }
119 1.1 christos }
120 1.1 christos printf("\nInput: %s", ibuf);
121 1.1 christos printf(" --> f = #%lx %lx %lx %lx\n", U u.bits[_0],
122 1.1 christos U u.bits[_1], U u.bits[_2], U u.bits[_3]);
123 1.1 christos goto fmt_test;
124 1.1 christos }
125 1.1 christos dItry = 1;
126 1.1 christos printf("\nInput: %s", ibuf);
127 1.1 christos i = strtorQ(ibuf, &se, r, u.bits);
128 1.1 christos if (r == 1 && (strtopQ(ibuf,&se1,v[0].bits) != i
129 1.1 christos || se != se1 || memcmp(u.bits, v[0].bits, 16)))
130 1.1 christos printf("***strtoQ and strtorQ disagree!!\n:");
131 1.1 christos printf("\nstrtoQ consumes %d bytes and returns %d\n",
132 1.1 christos (int)(se-ibuf), i);
133 1.1 christos printf("with bits = #%lx %lx %lx %lx\n",
134 1.1 christos U u.bits[_0], U u.bits[_1], U u.bits[_2], U u.bits[_3]);
135 1.1 christos fmt_test:
136 1.1 christos if (Ltest)
137 1.1 christos printf("printf(\"%%.35Lg\") gives %.35Lg\n", u.d);
138 1.1 christos se = g_Qfmt(obuf, u.bits, ndig, sizeof(obuf));
139 1.1 christos printf("g_Qfmt(%d) gives %d bytes: \"%s\"\n\n", ndig,
140 1.1 christos (int)(se-obuf), se ? obuf : "<null>");
141 1.1 christos if (!dItry)
142 1.1 christos continue;
143 1.1 christos printf("strtoIQ returns %d,",
144 1.1 christos strtoIQ(ibuf, &se, v[0].bits, v[1].bits));
145 1.1 christos printf(" consuming %d bytes.\n", (int)(se-ibuf));
146 1.1 christos if (!memcmp(v[0].bits, v[1].bits, 16)) {
147 1.1 christos if (!memcpy(u.bits, v[0].bits, 16))
148 1.1 christos printf("fI[0] == fI[1] == strtoQ\n");
149 1.1 christos else {
150 1.1 christos printf("fI[0] == fI[1] = #%lx %lx %lx %lx\n",
151 1.1 christos U v[0].bits[_0], U v[0].bits[_1],
152 1.1 christos U v[0].bits[_2], U v[0].bits[_3]);
153 1.1 christos if (Ltest)
154 1.1 christos printf("= %.35Lg\n", v[0].d);
155 1.1 christos }
156 1.1 christos }
157 1.1 christos else {
158 1.1 christos printf("fI[0] = #%lx %lx %lx %lx\n",
159 1.1 christos U v[0].bits[_0], U v[0].bits[_1],
160 1.1 christos U v[0].bits[_2], U v[0].bits[_3]);
161 1.1 christos if (Ltest)
162 1.1 christos printf("= %.35Lg\n", v[0].d);
163 1.1 christos printf("fI[1] = #%lx %lx %lx %lx\n",
164 1.1 christos U v[1].bits[_0], U v[1].bits[_1],
165 1.1 christos U v[1].bits[_2], U v[1].bits[_3]);
166 1.1 christos if (Ltest)
167 1.1 christos printf("= %.35Lg\n", v[1].d);
168 1.1 christos if (!memcmp(v[0].bits, u.bits, 16))
169 1.1 christos printf("fI[0] == strtod\n");
170 1.1 christos else if (!memcmp(v[1].bits, u.bits, 16))
171 1.1 christos printf("fI[1] == strtod\n");
172 1.1 christos else
173 1.1 christos printf("**** Both differ from strtod ****\n");
174 1.1 christos }
175 1.1 christos printf("\n");
176 1.1 christos }
177 1.1 christos return 0;
178 1.1 christos }
179