]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - 6/contrib/gdtoa/test/dt.c
merge fix for boot-time hang on centos' xen
[FreeBSD/FreeBSD.git] / 6 / 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
30         David M. Gay
31         Bell Laboratories, Room 2C-463
32         600 Mountain Avenue
33         Murray Hill, NJ 07974-0636
34         U.S.A.
35         dmg@bell-labs.com
36  */
37
38 /* Test program for strtod and dtoa.
39  *
40  * Inputs (on stdin):
41  *              number[: mode [ndigits]]
42  * or
43  *              #hex0 hex1[: mode [ndigits]]
44  * where number is a decimal floating-point number,
45  * hex0 is a string of Hex digits for the most significant
46  * word of the number, hex1 is a similar string for the other
47  * (least significant) word, and mode and ndigits are
48  * parameters to dtoa.
49  */
50
51 #include <stdio.h>
52 #include "gdtoa.h"
53 #ifdef KR_headers
54 #define Void /*void*/
55 #else
56 #define Void void
57 #endif
58
59 #ifdef __STDC__
60 #include <stdlib.h>
61 #else
62 #ifdef __cplusplus
63 extern "C" double atof(const char*);
64 #else
65 extern double atof ANSI((char*));
66 #endif
67 #endif
68 #ifdef IEEE_8087
69 #define word0(x) ((ULong *)&x)[1]
70 #define word1(x) ((ULong *)&x)[0]
71 #else
72 #define word0(x) ((ULong *)&x)[0]
73 #define word1(x) ((ULong *)&x)[1]
74 #endif
75 #include "errno.h"
76
77 #ifdef __cplusplus
78 extern "C" char *dtoa(double, int, int, int*, int*, char **);
79 #else
80 extern char *dtoa ANSI((double, int, int, int*, int*, char **));
81 #endif
82
83  static void
84 #ifdef KR_headers
85 g_fmt(b, x) char *b; double x;
86 #else
87 g_fmt(char *b, double x)
88 #endif
89 {
90         char *s, *se;
91         int decpt, i, j, k, sign;
92
93         if (!x) {
94                 *b++ = '0';
95                 *b = 0;
96                 return;
97                 }
98         s = dtoa(x, 0, 0, &decpt, &sign, &se);
99         if (sign)
100                 *b++ = '-';
101         if (decpt == 9999) /* Infinity or Nan */ {
102                 while(*b++ = *s++);
103                 return;
104                 }
105         if (decpt <= -4 || decpt > se - s + 5) {
106                 *b++ = *s++;
107                 if (*s) {
108                         *b++ = '.';
109                         while(*b = *s++)
110                                 b++;
111                         }
112                 *b++ = 'e';
113                 /* sprintf(b, "%+.2d", decpt - 1); */
114                 if (--decpt < 0) {
115                         *b++ = '-';
116                         decpt = -decpt;
117                         }
118                 else
119                         *b++ = '+';
120                 for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10){};
121                 for(;;) {
122                         i = decpt / k;
123                         *b++ = i + '0';
124                         if (--j <= 0)
125                                 break;
126                         decpt -= i*k;
127                         decpt *= 10;
128                         }
129                 *b = 0;
130                 }
131         else if (decpt <= 0) {
132                 *b++ = '.';
133                 for(; decpt < 0; decpt++)
134                         *b++ = '0';
135                 while(*b++ = *s++);
136                 }
137         else {
138                 while(*b = *s++) {
139                         b++;
140                         if (--decpt == 0 && *s)
141                                 *b++ = '.';
142                         }
143                 for(; decpt > 0; decpt--)
144                         *b++ = '0';
145                 *b = 0;
146                 }
147         }
148
149  static void
150 baderrno(Void)
151 {
152         fflush(stdout);
153         perror("\nerrno strtod");
154         fflush(stderr);
155         }
156
157 #define U (unsigned long)
158
159  static void
160 #ifdef KR_headers
161 check(d) double d;
162 #else
163 check(double d)
164 #endif
165 {
166         char buf[64];
167         int decpt, sign;
168         char *s, *se;
169         double d1;
170
171         s = dtoa(d, 0, 0, &decpt, &sign, &se);
172         sprintf(buf, "%s.%se%d", sign ? "-" : "", s, decpt);
173         errno = 0;
174         d1 = strtod(buf, (char **)0);
175         if (errno)
176                 baderrno();
177         if (d != d1) {
178                 printf("sent d = %.17g = 0x%lx %lx, buf = %s\n",
179                         d, U word0(d), U word1(d), buf);
180                 printf("got d1 = %.17g = 0x%lx %lx\n",
181                         d1, U word0(d1), U word1(d1));
182                 }
183         }
184
185 main(Void){
186         char buf[2048], buf1[32];
187         char *fmt, *s, *se;
188         double d, d1;
189         int decpt, sign;
190         int mode = 0, ndigits = 17;
191         ULong x, y;
192 #ifdef VAX
193         ULong z;
194 #endif
195
196         while(fgets(buf, sizeof(buf), stdin)) {
197                 if (*buf == '*') {
198                         printf("%s", buf);
199                         continue;
200                         }
201                 printf("Input: %s", buf);
202                 if (*buf == '#') {
203                         x = word0(d);
204                         y = word1(d);
205                         sscanf(buf+1, "%lx %lx:%d %d", &x, &y, &mode, &ndigits);
206                         word0(d) = x;
207                         word1(d) = y;
208                         fmt = "Output: d =\n%.17g = 0x%lx %lx\n";
209                         }
210                 else {
211                         errno = 0;
212                         d = strtod(buf,&se);
213                         if (*se == ':')
214                                 sscanf(se+1,"%d %d", &mode, &ndigits);
215                         d1 = atof(buf);
216                         fmt = "Output: d =\n%.17g = 0x%lx %lx, se = %s";
217                         if (errno)
218                                 baderrno();
219                         }
220                 printf(fmt, d, U word0(d), U word1(d), se);
221                 g_fmt(buf1, d);
222                 printf("\tg_fmt gives \"%s\"\n", buf1);
223                 if (*buf != '#' && d != d1)
224                         printf("atof gives\n\
225         d1 = %.17g = 0x%lx %lx\nversus\n\
226         d  = %.17g = 0x%lx %lx\n", d1, U word0(d1), U word1(d1),
227                                 d, U word0(d), U word1(d));
228                 check(d);
229                 s = dtoa(d, mode, ndigits, &decpt, &sign, &se);
230                 printf("\tdtoa(mode = %d, ndigits = %d):\n", mode, ndigits);
231                 printf("\tdtoa returns sign = %d, decpt = %d, %d digits:\n%s\n",
232                         sign, decpt, se-s, s);
233                 x = word1(d);
234                 if (x != 0xffffffff
235                  && (word0(d) & 0x7ff00000) != 0x7ff00000) {
236 #ifdef VAX
237                         z = x << 16 | x >> 16;
238                         z++;
239                         z = z << 16 | z >> 16;
240                         word1(d) = z;
241 #else
242                         word1(d) = x + 1;
243 #endif
244                         printf("\tnextafter(d,+Inf) = %.17g = 0x%lx %lx:\n",
245                                 d, U word0(d), U word1(d));
246                         g_fmt(buf1, d);
247                         printf("\tg_fmt gives \"%s\"\n", buf1);
248                         s = dtoa(d, mode, ndigits, &decpt, &sign, &se);
249                         printf(
250                 "\tdtoa returns sign = %d, decpt = %d, %d digits:\n%s\n",
251                                 sign, decpt, se-s, s);
252                         check(d);
253                         }
254                 if (x) {
255 #ifdef VAX
256                         z = x << 16 | x >> 16;
257                         z--;
258                         z = z << 16 | z >> 16;
259                         word1(d) = z;
260 #else
261                         word1(d) = x - 1;
262 #endif
263                         printf("\tnextafter(d,-Inf) = %.17g = 0x%lx %lx:\n",
264                                 d, U word0(d), U word1(d));
265                         g_fmt(buf1, d);
266                         printf("\tg_fmt gives \"%s\"\n", buf1);
267                         s = dtoa(d, mode, ndigits, &decpt, &sign, &se);
268                         printf(
269                 "\tdtoa returns sign = %d, decpt = %d, %d digits:\n%s\n",
270                                 sign, decpt, se-s, s);
271                         check(d);
272                         }
273                 }
274         return 0;
275         }