]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - contrib/gdtoa/test/dt.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / contrib / gdtoa / test / dt.c
1 /****************************************************************
2
3 The author of this software is David M. Gay.
4
5 Copyright (C) 1998 by Lucent Technologies
6 All Rights Reserved
7
8 Permission to use, copy, modify, and distribute this software and
9 its documentation for any purpose and without fee is hereby
10 granted, provided that the above copyright notice appear in all
11 copies and that both that the copyright notice and this
12 permission notice and warranty disclaimer appear in supporting
13 documentation, and that the name of Lucent or any of its entities
14 not be used in advertising or publicity pertaining to
15 distribution of the software without specific, written prior
16 permission.
17
18 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
20 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
21 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
23 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
24 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
25 THIS SOFTWARE.
26
27 ****************************************************************/
28
29 /* Please send bug reports to David M. Gay (dmg at acm dot org,
30  * with " at " changed at "@" and " dot " changed to ".").      */
31
32 /* Test program for strtod and dtoa.
33  *
34  * Inputs (on stdin):
35  *              number[: mode [ndigits]]
36  * or
37  *              #hex0 hex1[: mode [ndigits]]
38  * where number is a decimal floating-point number,
39  * hex0 is a string of Hex digits for the most significant
40  * word of the number, hex1 is a similar string for the other
41  * (least significant) word, and mode and ndigits are
42  * parameters to dtoa.
43  */
44
45 #include <stdio.h>
46 #include "gdtoa.h"
47 #ifdef KR_headers
48 #define Void /*void*/
49 #else
50 #define Void void
51 #endif
52
53 #ifdef __STDC__
54 #include <stdlib.h>
55 #else
56 #ifdef __cplusplus
57 extern "C" double atof(const char*);
58 #else
59 extern double atof ANSI((char*));
60 #endif
61 #endif
62 #ifdef IEEE_8087
63 #define word0(x) ((ULong *)&x)[1]
64 #define word1(x) ((ULong *)&x)[0]
65 #else
66 #define word0(x) ((ULong *)&x)[0]
67 #define word1(x) ((ULong *)&x)[1]
68 #endif
69 #include "errno.h"
70
71 #ifdef __cplusplus
72 extern "C" char *dtoa(double, int, int, int*, int*, char **);
73 #else
74 extern char *dtoa ANSI((double, int, int, int*, int*, char **));
75 #endif
76
77  static void
78 #ifdef KR_headers
79 g_fmt(b, x) char *b; double x;
80 #else
81 g_fmt(char *b, double x)
82 #endif
83 {
84         char *s, *se;
85         int decpt, i, j, k, sign;
86
87         if (!x) {
88                 *b++ = '0';
89                 *b = 0;
90                 return;
91                 }
92         s = dtoa(x, 0, 0, &decpt, &sign, &se);
93         if (sign)
94                 *b++ = '-';
95         if (decpt == 9999) /* Infinity or Nan */ {
96                 while(*b++ = *s++);
97                 return;
98                 }
99         if (decpt <= -4 || decpt > se - s + 5) {
100                 *b++ = *s++;
101                 if (*s) {
102                         *b++ = '.';
103                         while(*b = *s++)
104                                 b++;
105                         }
106                 *b++ = 'e';
107                 /* sprintf(b, "%+.2d", decpt - 1); */
108                 if (--decpt < 0) {
109                         *b++ = '-';
110                         decpt = -decpt;
111                         }
112                 else
113                         *b++ = '+';
114                 for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10){};
115                 for(;;) {
116                         i = decpt / k;
117                         *b++ = i + '0';
118                         if (--j <= 0)
119                                 break;
120                         decpt -= i*k;
121                         decpt *= 10;
122                         }
123                 *b = 0;
124                 }
125         else if (decpt <= 0) {
126                 *b++ = '.';
127                 for(; decpt < 0; decpt++)
128                         *b++ = '0';
129                 while(*b++ = *s++);
130                 }
131         else {
132                 while(*b = *s++) {
133                         b++;
134                         if (--decpt == 0 && *s)
135                                 *b++ = '.';
136                         }
137                 for(; decpt > 0; decpt--)
138                         *b++ = '0';
139                 *b = 0;
140                 }
141         }
142
143  static void
144 baderrno(Void)
145 {
146         fflush(stdout);
147         perror("\nerrno strtod");
148         fflush(stderr);
149         }
150
151 #define U (unsigned long)
152
153  static void
154 #ifdef KR_headers
155 check(d) double d;
156 #else
157 check(double d)
158 #endif
159 {
160         char buf[64];
161         int decpt, sign;
162         char *s, *se;
163         double d1;
164
165         s = dtoa(d, 0, 0, &decpt, &sign, &se);
166         sprintf(buf, "%s%s%se%d", sign ? "-" : "",
167                 decpt == 9999 ? "" : ".", s, decpt);
168         errno = 0;
169         d1 = strtod(buf, (char **)0);
170         if (errno)
171                 baderrno();
172         if (d != d1) {
173                 printf("sent d = %.17g = 0x%lx %lx, buf = %s\n",
174                         d, U word0(d), U word1(d), buf);
175                 printf("got d1 = %.17g = 0x%lx %lx\n",
176                         d1, U word0(d1), U word1(d1));
177                 }
178         }
179
180  int
181 main(Void){
182         char buf[2048], buf1[32];
183         char *fmt, *s, *s1, *se;
184         double d, d1;
185         int decpt, sign;
186         int mode = 0, ndigits = 17;
187         ULong x, y;
188 #ifdef VAX
189         ULong z;
190 #endif
191
192         while(fgets(buf, sizeof(buf), stdin)) {
193                 if (*buf == '*') {
194                         printf("%s", buf);
195                         continue;
196                         }
197                 printf("Input: %s", buf);
198                 if (*buf == '#') {
199                         x = word0(d);
200                         y = word1(d);
201                         /* sscanf(buf+1, "%lx %lx:%d %d", &x, &y, &mode, &ndigits); */
202                         x = (ULong)strtoul(s1 = buf+1, &se, 16);
203                         if (se > s1) {
204                                 y = (ULong)strtoul(s1 = se, &se, 16);
205                                 if (se > s1)
206                                         sscanf(se, ":%d %d", &mode, &ndigits);
207                                 }
208                         word0(d) = x;
209                         word1(d) = y;
210                         fmt = "Output: d =\n%.17g = 0x%lx %lx\n";
211                         }
212                 else {
213                         errno = 0;
214                         d = strtod(buf,&se);
215                         if (*se == ':')
216                                 sscanf(se+1,"%d %d", &mode, &ndigits);
217                         d1 = atof(buf);
218                         fmt = "Output: d =\n%.17g = 0x%lx %lx, se = %s";
219                         if (errno)
220                                 baderrno();
221                         }
222                 printf(fmt, d, U word0(d), U word1(d), se);
223                 g_fmt(buf1, d);
224                 printf("\tg_fmt gives \"%s\"\n", buf1);
225                 if (*buf != '#' && d != d1)
226                         printf("atof gives\n\
227         d1 = %.17g = 0x%lx %lx\nversus\n\
228         d  = %.17g = 0x%lx %lx\n", d1, U word0(d1), U word1(d1),
229                                 d, U word0(d), U word1(d));
230                 check(d);
231                 s = dtoa(d, mode, ndigits, &decpt, &sign, &se);
232                 printf("\tdtoa(mode = %d, ndigits = %d):\n", mode, ndigits);
233                 printf("\tdtoa returns sign = %d, decpt = %d, %d digits:\n%s\n",
234                         sign, decpt, se-s, s);
235                 x = word1(d);
236                 if (x != 0xffffffff
237                  && (word0(d) & 0x7ff00000) != 0x7ff00000) {
238 #ifdef VAX
239                         z = x << 16 | x >> 16;
240                         z++;
241                         z = z << 16 | z >> 16;
242                         word1(d) = z;
243 #else
244                         word1(d) = x + 1;
245 #endif
246                         printf("\tnextafter(d,+Inf) = %.17g = 0x%lx %lx:\n",
247                                 d, U word0(d), U word1(d));
248                         g_fmt(buf1, d);
249                         printf("\tg_fmt gives \"%s\"\n", buf1);
250                         s = dtoa(d, mode, ndigits, &decpt, &sign, &se);
251                         printf(
252                 "\tdtoa returns sign = %d, decpt = %d, %d digits:\n%s\n",
253                                 sign, decpt, se-s, s);
254                         check(d);
255                         }
256                 if (x) {
257 #ifdef VAX
258                         z = x << 16 | x >> 16;
259                         z--;
260                         z = z << 16 | z >> 16;
261                         word1(d) = z;
262 #else
263                         word1(d) = x - 1;
264 #endif
265                         printf("\tnextafter(d,-Inf) = %.17g = 0x%lx %lx:\n",
266                                 d, U word0(d), U word1(d));
267                         g_fmt(buf1, d);
268                         printf("\tg_fmt gives \"%s\"\n", buf1);
269                         s = dtoa(d, mode, ndigits, &decpt, &sign, &se);
270                         printf(
271                 "\tdtoa returns sign = %d, decpt = %d, %d digits:\n%s\n",
272                                 sign, decpt, se-s, s);
273                         check(d);
274                         }
275                 }
276         return 0;
277         }