Commit | Line | Data |
---|---|---|
f1525c23 WH |
1 | /**************************************************************** |
2 | Copyright 1990, 1993 by AT&T Bell Laboratories and Bellcore. | |
3 | ||
4 | Permission to use, copy, modify, and distribute this software | |
5 | and its documentation for any purpose and without fee is hereby | |
6 | granted, provided that the above copyright notice appear in all | |
7 | copies and that both that the copyright notice and this | |
8 | permission notice and warranty disclaimer appear in supporting | |
9 | documentation, and that the names of AT&T Bell Laboratories or | |
10 | Bellcore or any of their entities not be used in advertising or | |
11 | publicity pertaining to distribution of the software without | |
12 | specific, written prior permission. | |
13 | ||
14 | AT&T and Bellcore disclaim all warranties with regard to this | |
15 | software, including all implied warranties of merchantability | |
16 | and fitness. In no event shall AT&T or Bellcore be liable for | |
17 | any special, indirect or consequential damages or any damages | |
18 | whatsoever resulting from loss of use, data or profits, whether | |
19 | in an action of contract, negligence or other tortious action, | |
20 | arising out of or in connection with the use or performance of | |
21 | this software. | |
22 | ****************************************************************/ | |
23 | ||
24 | /* Put strings representing decimal floating-point numbers | |
25 | * into canonical form: always have a decimal point or | |
26 | * exponent field; if using an exponent field, have the | |
27 | * number before it start with a digit and decimal point | |
28 | * (if the number has more than one digit); only have an | |
29 | * exponent field if it saves space. | |
30 | * | |
31 | * Arrange that the return value, rv, satisfies rv[0] == '-' || rv[-1] == '-' . | |
32 | */ | |
33 | ||
34 | #include "sysdep.h" | |
35 | ||
36 | char * | |
37 | cds(s, z0) | |
38 | char *s, *z0; | |
39 | { | |
40 | int ea, esign, et, i, k, nd = 0, sign = 0, tz; | |
41 | char c, *z; | |
42 | char ebuf[24]; | |
43 | long ex = 0; | |
44 | static char etype[Table_size], *db; | |
45 | static int dblen = 64; | |
46 | ||
47 | if (!db) { | |
48 | etype['E'] = 1; | |
49 | etype['e'] = 1; | |
50 | etype['D'] = 1; | |
51 | etype['d'] = 1; | |
52 | etype['+'] = 2; | |
53 | etype['-'] = 3; | |
54 | db = Alloc(dblen); | |
55 | } | |
56 | ||
57 | while((c = *s++) == '0'); | |
58 | if (c == '-') | |
59 | { sign = 1; c = *s++; } | |
60 | else if (c == '+') | |
61 | c = *s++; | |
62 | k = strlen(s) + 2; | |
63 | if (k >= dblen) { | |
64 | do dblen <<= 1; | |
65 | while(k >= dblen); | |
66 | free(db); | |
67 | db = Alloc(dblen); | |
68 | } | |
69 | if (etype[(unsigned char)c] >= 2) | |
70 | while(c == '0') c = *s++; | |
71 | tz = 0; | |
72 | while(c >= '0' && c <= '9') { | |
73 | if (c == '0') | |
74 | tz++; | |
75 | else { | |
76 | if (nd) | |
77 | for(; tz; --tz) | |
78 | db[nd++] = '0'; | |
79 | else | |
80 | tz = 0; | |
81 | db[nd++] = c; | |
82 | } | |
83 | c = *s++; | |
84 | } | |
85 | ea = -tz; | |
86 | if (c == '.') { | |
87 | while((c = *s++) >= '0' && c <= '9') { | |
88 | if (c == '0') | |
89 | tz++; | |
90 | else { | |
91 | if (tz) { | |
92 | ea += tz; | |
93 | if (nd) | |
94 | for(; tz; --tz) | |
95 | db[nd++] = '0'; | |
96 | else | |
97 | tz = 0; | |
98 | } | |
99 | db[nd++] = c; | |
100 | ea++; | |
101 | } | |
102 | } | |
103 | } | |
104 | if (et = etype[(unsigned char)c]) { | |
105 | esign = et == 3; | |
106 | c = *s++; | |
107 | if (et == 1) { | |
108 | if(etype[(unsigned char)c] > 1) { | |
109 | if (c == '-') | |
110 | esign = 1; | |
111 | c = *s++; | |
112 | } | |
113 | } | |
114 | while(c >= '0' && c <= '9') { | |
115 | ex = 10*ex + (c - '0'); | |
116 | c = *s++; | |
117 | } | |
118 | if (esign) | |
119 | ex = -ex; | |
120 | } | |
121 | switch(c) { | |
122 | case 0: | |
123 | break; | |
124 | #ifndef VAX | |
125 | case 'i': | |
126 | case 'I': | |
127 | Fatal("Overflow evaluating constant expression."); | |
128 | case 'n': | |
129 | case 'N': | |
130 | Fatal("Constant expression yields NaN."); | |
131 | #endif | |
132 | default: | |
133 | Fatal("unexpected character in cds."); | |
134 | } | |
135 | ex -= ea; | |
136 | if (!nd) { | |
137 | if (!z0) | |
138 | z0 = mem(4,0); | |
139 | strcpy(z0, "-0."); | |
140 | sign = 0; | |
141 | } | |
142 | else if (ex > 2 || ex + nd < -2) { | |
143 | sprintf(ebuf, "%ld", ex + nd - 1); | |
144 | k = strlen(ebuf) + nd + 3; | |
145 | if (nd > 1) | |
146 | k++; | |
147 | if (!z0) | |
148 | z0 = mem(k,0); | |
149 | z = z0; | |
150 | *z++ = '-'; | |
151 | *z++ = *db; | |
152 | if (nd > 1) { | |
153 | *z++ = '.'; | |
154 | for(k = 1; k < nd; k++) | |
155 | *z++ = db[k]; | |
156 | } | |
157 | *z++ = 'e'; | |
158 | strcpy(z, ebuf); | |
159 | } | |
160 | else { | |
161 | k = (int)(ex + nd); | |
162 | i = nd + 3; | |
163 | if (k < 0) | |
164 | i -= k; | |
165 | else if (ex > 0) | |
166 | i += ex; | |
167 | if (!z0) | |
168 | z0 = mem(i,0); | |
169 | z = z0; | |
170 | *z++ = '-'; | |
171 | if (ex >= 0) { | |
172 | for(k = 0; k < nd; k++) | |
173 | *z++ = db[k]; | |
174 | while(--ex >= 0) | |
175 | *z++ = '0'; | |
176 | *z++ = '.'; | |
177 | } | |
178 | else { | |
179 | for(i = 0; i < k;) | |
180 | *z++ = db[i++]; | |
181 | *z++ = '.'; | |
182 | while(++k <= 0) | |
183 | *z++ = '0'; | |
184 | while(i < nd) | |
185 | *z++ = db[i++]; | |
186 | } | |
187 | *z = 0; | |
188 | } | |
189 | return sign ? z0 : z0+1; | |
190 | } |