atof-generic.c revision 1.6 1 1.1 christos /* atof_generic.c - turn a string of digits into a Flonum
2 1.6 christos Copyright (C) 1987-2018 Free Software Foundation, Inc.
3 1.1 christos
4 1.1 christos This file is part of GAS, the GNU Assembler.
5 1.1 christos
6 1.1 christos GAS is free software; you can redistribute it and/or modify
7 1.1 christos it under the terms of the GNU General Public License as published by
8 1.1 christos the Free Software Foundation; either version 3, or (at your option)
9 1.1 christos any later version.
10 1.1 christos
11 1.1 christos GAS is distributed in the hope that it will be useful, but WITHOUT
12 1.1 christos ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 1.1 christos or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 1.1 christos License for more details.
15 1.1 christos
16 1.1 christos You should have received a copy of the GNU General Public License
17 1.1 christos along with GAS; see the file COPYING. If not, write to the Free
18 1.1 christos Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19 1.1 christos 02110-1301, USA. */
20 1.1 christos
21 1.1 christos #include "as.h"
22 1.1 christos #include "safe-ctype.h"
23 1.1 christos
24 1.1 christos #ifndef FALSE
25 1.1 christos #define FALSE (0)
26 1.1 christos #endif
27 1.1 christos #ifndef TRUE
28 1.1 christos #define TRUE (1)
29 1.1 christos #endif
30 1.1 christos
31 1.1 christos #ifdef TRACE
32 1.1 christos static void flonum_print (const FLONUM_TYPE *);
33 1.1 christos #endif
34 1.1 christos
35 1.1 christos #define ASSUME_DECIMAL_MARK_IS_DOT
36 1.1 christos
37 1.1 christos /***********************************************************************\
38 1.1 christos * *
39 1.1 christos * Given a string of decimal digits , with optional decimal *
40 1.1 christos * mark and optional decimal exponent (place value) of the *
41 1.1 christos * lowest_order decimal digit: produce a floating point *
42 1.1 christos * number. The number is 'generic' floating point: our *
43 1.1 christos * caller will encode it for a specific machine architecture. *
44 1.1 christos * *
45 1.1 christos * Assumptions *
46 1.1 christos * uses base (radix) 2 *
47 1.1 christos * this machine uses 2's complement binary integers *
48 1.1 christos * target flonums use " " " " *
49 1.1 christos * target flonums exponents fit in a long *
50 1.1 christos * *
51 1.1 christos \***********************************************************************/
52 1.1 christos
53 1.1 christos /*
54 1.1 christos
55 1.1 christos Syntax:
56 1.1 christos
57 1.1 christos <flonum> ::= <optional-sign> <decimal-number> <optional-exponent>
58 1.1 christos <optional-sign> ::= '+' | '-' | {empty}
59 1.1 christos <decimal-number> ::= <integer>
60 1.1 christos | <integer> <radix-character>
61 1.1 christos | <integer> <radix-character> <integer>
62 1.1 christos | <radix-character> <integer>
63 1.1 christos
64 1.1 christos <optional-exponent> ::= {empty}
65 1.1 christos | <exponent-character> <optional-sign> <integer>
66 1.1 christos
67 1.1 christos <integer> ::= <digit> | <digit> <integer>
68 1.1 christos <digit> ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
69 1.1 christos <exponent-character> ::= {one character from "string_of_decimal_exponent_marks"}
70 1.1 christos <radix-character> ::= {one character from "string_of_decimal_marks"}
71 1.1 christos
72 1.1 christos */
73 1.1 christos
74 1.1 christos int
75 1.1 christos atof_generic (/* return pointer to just AFTER number we read. */
76 1.1 christos char **address_of_string_pointer,
77 1.1 christos /* At most one per number. */
78 1.1 christos const char *string_of_decimal_marks,
79 1.1 christos const char *string_of_decimal_exponent_marks,
80 1.1 christos FLONUM_TYPE *address_of_generic_floating_point_number)
81 1.1 christos {
82 1.1 christos int return_value; /* 0 means OK. */
83 1.1 christos char *first_digit;
84 1.1 christos unsigned int number_of_digits_before_decimal;
85 1.1 christos unsigned int number_of_digits_after_decimal;
86 1.1 christos long decimal_exponent;
87 1.1 christos unsigned int number_of_digits_available;
88 1.1 christos char digits_sign_char;
89 1.1 christos
90 1.1 christos /*
91 1.1 christos * Scan the input string, abstracting (1)digits (2)decimal mark (3) exponent.
92 1.1 christos * It would be simpler to modify the string, but we don't; just to be nice
93 1.1 christos * to caller.
94 1.1 christos * We need to know how many digits we have, so we can allocate space for
95 1.1 christos * the digits' value.
96 1.1 christos */
97 1.1 christos
98 1.1 christos char *p;
99 1.1 christos char c;
100 1.1 christos int seen_significant_digit;
101 1.1 christos
102 1.1 christos #ifdef ASSUME_DECIMAL_MARK_IS_DOT
103 1.1 christos gas_assert (string_of_decimal_marks[0] == '.'
104 1.1 christos && string_of_decimal_marks[1] == 0);
105 1.1 christos #define IS_DECIMAL_MARK(c) ((c) == '.')
106 1.1 christos #else
107 1.1 christos #define IS_DECIMAL_MARK(c) (0 != strchr (string_of_decimal_marks, (c)))
108 1.1 christos #endif
109 1.1 christos
110 1.1 christos first_digit = *address_of_string_pointer;
111 1.1 christos c = *first_digit;
112 1.1 christos
113 1.1 christos if (c == '-' || c == '+')
114 1.1 christos {
115 1.1 christos digits_sign_char = c;
116 1.1 christos first_digit++;
117 1.1 christos }
118 1.1 christos else
119 1.1 christos digits_sign_char = '+';
120 1.1 christos
121 1.1 christos switch (first_digit[0])
122 1.1 christos {
123 1.1 christos case 's':
124 1.1 christos case 'S':
125 1.1 christos if (!strncasecmp ("snan", first_digit, 4))
126 1.1 christos {
127 1.1 christos address_of_generic_floating_point_number->sign = 0;
128 1.1 christos address_of_generic_floating_point_number->exponent = 0;
129 1.1 christos address_of_generic_floating_point_number->leader =
130 1.1 christos address_of_generic_floating_point_number->low;
131 1.1 christos *address_of_string_pointer = first_digit + 4;
132 1.1 christos return 0;
133 1.1 christos }
134 1.1 christos break;
135 1.1 christos
136 1.1 christos case 'q':
137 1.1 christos case 'Q':
138 1.1 christos if (!strncasecmp ("qnan", first_digit, 4))
139 1.1 christos {
140 1.1 christos address_of_generic_floating_point_number->sign = 0;
141 1.1 christos address_of_generic_floating_point_number->exponent = 0;
142 1.1 christos address_of_generic_floating_point_number->leader =
143 1.1 christos address_of_generic_floating_point_number->low;
144 1.1 christos *address_of_string_pointer = first_digit + 4;
145 1.1 christos return 0;
146 1.1 christos }
147 1.1 christos break;
148 1.1 christos
149 1.1 christos case 'n':
150 1.1 christos case 'N':
151 1.1 christos if (!strncasecmp ("nan", first_digit, 3))
152 1.1 christos {
153 1.1 christos address_of_generic_floating_point_number->sign = 0;
154 1.1 christos address_of_generic_floating_point_number->exponent = 0;
155 1.1 christos address_of_generic_floating_point_number->leader =
156 1.1 christos address_of_generic_floating_point_number->low;
157 1.1 christos *address_of_string_pointer = first_digit + 3;
158 1.1 christos return 0;
159 1.1 christos }
160 1.1 christos break;
161 1.1 christos
162 1.1 christos case 'i':
163 1.1 christos case 'I':
164 1.1 christos if (!strncasecmp ("inf", first_digit, 3))
165 1.1 christos {
166 1.1 christos address_of_generic_floating_point_number->sign =
167 1.1 christos digits_sign_char == '+' ? 'P' : 'N';
168 1.1 christos address_of_generic_floating_point_number->exponent = 0;
169 1.1 christos address_of_generic_floating_point_number->leader =
170 1.1 christos address_of_generic_floating_point_number->low;
171 1.1 christos
172 1.1 christos first_digit += 3;
173 1.1 christos if (!strncasecmp ("inity", first_digit, 5))
174 1.1 christos first_digit += 5;
175 1.1 christos
176 1.1 christos *address_of_string_pointer = first_digit;
177 1.1 christos
178 1.1 christos return 0;
179 1.1 christos }
180 1.1 christos break;
181 1.1 christos }
182 1.1 christos
183 1.1 christos number_of_digits_before_decimal = 0;
184 1.1 christos number_of_digits_after_decimal = 0;
185 1.1 christos decimal_exponent = 0;
186 1.1 christos seen_significant_digit = 0;
187 1.1 christos for (p = first_digit;
188 1.1 christos (((c = *p) != '\0')
189 1.1 christos && (!c || !IS_DECIMAL_MARK (c))
190 1.1 christos && (!c || !strchr (string_of_decimal_exponent_marks, c)));
191 1.1 christos p++)
192 1.1 christos {
193 1.1 christos if (ISDIGIT (c))
194 1.1 christos {
195 1.1 christos if (seen_significant_digit || c > '0')
196 1.1 christos {
197 1.1 christos ++number_of_digits_before_decimal;
198 1.1 christos seen_significant_digit = 1;
199 1.1 christos }
200 1.1 christos else
201 1.1 christos {
202 1.1 christos first_digit++;
203 1.1 christos }
204 1.1 christos }
205 1.1 christos else
206 1.1 christos {
207 1.1 christos break; /* p -> char after pre-decimal digits. */
208 1.1 christos }
209 1.1 christos } /* For each digit before decimal mark. */
210 1.1 christos
211 1.1 christos #ifndef OLD_FLOAT_READS
212 1.1 christos /* Ignore trailing 0's after the decimal point. The original code here
213 1.1 christos * (ifdef'd out) does not do this, and numbers like
214 1.1 christos * 4.29496729600000000000e+09 (2**31)
215 1.1 christos * come out inexact for some reason related to length of the digit
216 1.1 christos * string.
217 1.1 christos */
218 1.1 christos if (c && IS_DECIMAL_MARK (c))
219 1.1 christos {
220 1.1 christos unsigned int zeros = 0; /* Length of current string of zeros */
221 1.1 christos
222 1.1 christos for (p++; (c = *p) && ISDIGIT (c); p++)
223 1.1 christos {
224 1.1 christos if (c == '0')
225 1.1 christos {
226 1.1 christos zeros++;
227 1.1 christos }
228 1.1 christos else
229 1.1 christos {
230 1.1 christos number_of_digits_after_decimal += 1 + zeros;
231 1.1 christos zeros = 0;
232 1.1 christos }
233 1.1 christos }
234 1.1 christos }
235 1.1 christos #else
236 1.1 christos if (c && IS_DECIMAL_MARK (c))
237 1.1 christos {
238 1.1 christos for (p++;
239 1.1 christos (((c = *p) != '\0')
240 1.1 christos && (!c || !strchr (string_of_decimal_exponent_marks, c)));
241 1.1 christos p++)
242 1.1 christos {
243 1.1 christos if (ISDIGIT (c))
244 1.1 christos {
245 1.1 christos /* This may be retracted below. */
246 1.1 christos number_of_digits_after_decimal++;
247 1.1 christos
248 1.1 christos if ( /* seen_significant_digit || */ c > '0')
249 1.1 christos {
250 1.1 christos seen_significant_digit = TRUE;
251 1.1 christos }
252 1.1 christos }
253 1.1 christos else
254 1.1 christos {
255 1.1 christos if (!seen_significant_digit)
256 1.1 christos {
257 1.1 christos number_of_digits_after_decimal = 0;
258 1.1 christos }
259 1.1 christos break;
260 1.1 christos }
261 1.1 christos } /* For each digit after decimal mark. */
262 1.1 christos }
263 1.1 christos
264 1.1 christos while (number_of_digits_after_decimal
265 1.1 christos && first_digit[number_of_digits_before_decimal
266 1.1 christos + number_of_digits_after_decimal] == '0')
267 1.1 christos --number_of_digits_after_decimal;
268 1.1 christos #endif
269 1.1 christos
270 1.1 christos if (flag_m68k_mri)
271 1.1 christos {
272 1.1 christos while (c == '_')
273 1.1 christos c = *++p;
274 1.1 christos }
275 1.1 christos if (c && strchr (string_of_decimal_exponent_marks, c))
276 1.1 christos {
277 1.1 christos char digits_exponent_sign_char;
278 1.1 christos
279 1.1 christos c = *++p;
280 1.1 christos if (flag_m68k_mri)
281 1.1 christos {
282 1.1 christos while (c == '_')
283 1.1 christos c = *++p;
284 1.1 christos }
285 1.1 christos if (c && strchr ("+-", c))
286 1.1 christos {
287 1.1 christos digits_exponent_sign_char = c;
288 1.1 christos c = *++p;
289 1.1 christos }
290 1.1 christos else
291 1.1 christos {
292 1.1 christos digits_exponent_sign_char = '+';
293 1.1 christos }
294 1.1 christos
295 1.1 christos for (; (c); c = *++p)
296 1.1 christos {
297 1.1 christos if (ISDIGIT (c))
298 1.1 christos {
299 1.1 christos decimal_exponent = decimal_exponent * 10 + c - '0';
300 1.1 christos /*
301 1.1 christos * BUG! If we overflow here, we lose!
302 1.1 christos */
303 1.1 christos }
304 1.1 christos else
305 1.1 christos {
306 1.1 christos break;
307 1.1 christos }
308 1.1 christos }
309 1.1 christos
310 1.1 christos if (digits_exponent_sign_char == '-')
311 1.1 christos {
312 1.1 christos decimal_exponent = -decimal_exponent;
313 1.1 christos }
314 1.1 christos }
315 1.1 christos
316 1.1 christos *address_of_string_pointer = p;
317 1.1 christos
318 1.1 christos number_of_digits_available =
319 1.1 christos number_of_digits_before_decimal + number_of_digits_after_decimal;
320 1.1 christos return_value = 0;
321 1.1 christos if (number_of_digits_available == 0)
322 1.1 christos {
323 1.1 christos address_of_generic_floating_point_number->exponent = 0; /* Not strictly necessary */
324 1.1 christos address_of_generic_floating_point_number->leader
325 1.1 christos = -1 + address_of_generic_floating_point_number->low;
326 1.1 christos address_of_generic_floating_point_number->sign = digits_sign_char;
327 1.1 christos /* We have just concocted (+/-)0.0E0 */
328 1.1 christos
329 1.1 christos }
330 1.1 christos else
331 1.1 christos {
332 1.1 christos int count; /* Number of useful digits left to scan. */
333 1.1 christos
334 1.5 christos LITTLENUM_TYPE *temporary_binary_low = NULL;
335 1.5 christos LITTLENUM_TYPE *power_binary_low = NULL;
336 1.1 christos LITTLENUM_TYPE *digits_binary_low;
337 1.1 christos unsigned int precision;
338 1.1 christos unsigned int maximum_useful_digits;
339 1.1 christos unsigned int number_of_digits_to_use;
340 1.1 christos unsigned int more_than_enough_bits_for_digits;
341 1.1 christos unsigned int more_than_enough_littlenums_for_digits;
342 1.1 christos unsigned int size_of_digits_in_littlenums;
343 1.1 christos unsigned int size_of_digits_in_chars;
344 1.1 christos FLONUM_TYPE power_of_10_flonum;
345 1.1 christos FLONUM_TYPE digits_flonum;
346 1.1 christos
347 1.1 christos precision = (address_of_generic_floating_point_number->high
348 1.1 christos - address_of_generic_floating_point_number->low
349 1.1 christos + 1); /* Number of destination littlenums. */
350 1.1 christos
351 1.1 christos /* Includes guard bits (two littlenums worth) */
352 1.1 christos maximum_useful_digits = (((precision - 2))
353 1.1 christos * ( (LITTLENUM_NUMBER_OF_BITS))
354 1.1 christos * 1000000 / 3321928)
355 1.1 christos + 2; /* 2 :: guard digits. */
356 1.1 christos
357 1.1 christos if (number_of_digits_available > maximum_useful_digits)
358 1.1 christos {
359 1.1 christos number_of_digits_to_use = maximum_useful_digits;
360 1.1 christos }
361 1.1 christos else
362 1.1 christos {
363 1.1 christos number_of_digits_to_use = number_of_digits_available;
364 1.1 christos }
365 1.1 christos
366 1.1 christos /* Cast these to SIGNED LONG first, otherwise, on systems with
367 1.1 christos LONG wider than INT (such as Alpha OSF/1), unsignedness may
368 1.1 christos cause unexpected results. */
369 1.1 christos decimal_exponent += ((long) number_of_digits_before_decimal
370 1.1 christos - (long) number_of_digits_to_use);
371 1.1 christos
372 1.1 christos more_than_enough_bits_for_digits
373 1.1 christos = (number_of_digits_to_use * 3321928 / 1000000 + 1);
374 1.1 christos
375 1.1 christos more_than_enough_littlenums_for_digits
376 1.1 christos = (more_than_enough_bits_for_digits
377 1.1 christos / LITTLENUM_NUMBER_OF_BITS)
378 1.1 christos + 2;
379 1.1 christos
380 1.1 christos /* Compute (digits) part. In "12.34E56" this is the "1234" part.
381 1.1 christos Arithmetic is exact here. If no digits are supplied then this
382 1.1 christos part is a 0 valued binary integer. Allocate room to build up
383 1.1 christos the binary number as littlenums. We want this memory to
384 1.1 christos disappear when we leave this function. Assume no alignment
385 1.1 christos problems => (room for n objects) == n * (room for 1
386 1.1 christos object). */
387 1.1 christos
388 1.1 christos size_of_digits_in_littlenums = more_than_enough_littlenums_for_digits;
389 1.1 christos size_of_digits_in_chars = size_of_digits_in_littlenums
390 1.1 christos * sizeof (LITTLENUM_TYPE);
391 1.1 christos
392 1.1 christos digits_binary_low = (LITTLENUM_TYPE *)
393 1.5 christos xmalloc (size_of_digits_in_chars);
394 1.1 christos
395 1.1 christos memset ((char *) digits_binary_low, '\0', size_of_digits_in_chars);
396 1.1 christos
397 1.1 christos /* Digits_binary_low[] is allocated and zeroed. */
398 1.1 christos
399 1.1 christos /*
400 1.1 christos * Parse the decimal digits as if * digits_low was in the units position.
401 1.1 christos * Emit a binary number into digits_binary_low[].
402 1.1 christos *
403 1.1 christos * Use a large-precision version of:
404 1.1 christos * (((1st-digit) * 10 + 2nd-digit) * 10 + 3rd-digit ...) * 10 + last-digit
405 1.1 christos */
406 1.1 christos
407 1.1 christos for (p = first_digit, count = number_of_digits_to_use; count; p++, --count)
408 1.1 christos {
409 1.1 christos c = *p;
410 1.1 christos if (ISDIGIT (c))
411 1.1 christos {
412 1.1 christos /*
413 1.1 christos * Multiply by 10. Assume can never overflow.
414 1.1 christos * Add this digit to digits_binary_low[].
415 1.1 christos */
416 1.1 christos
417 1.1 christos long carry;
418 1.1 christos LITTLENUM_TYPE *littlenum_pointer;
419 1.1 christos LITTLENUM_TYPE *littlenum_limit;
420 1.1 christos
421 1.1 christos littlenum_limit = digits_binary_low
422 1.1 christos + more_than_enough_littlenums_for_digits
423 1.1 christos - 1;
424 1.1 christos
425 1.1 christos carry = c - '0'; /* char -> binary */
426 1.1 christos
427 1.1 christos for (littlenum_pointer = digits_binary_low;
428 1.1 christos littlenum_pointer <= littlenum_limit;
429 1.1 christos littlenum_pointer++)
430 1.1 christos {
431 1.1 christos long work;
432 1.1 christos
433 1.1 christos work = carry + 10 * (long) (*littlenum_pointer);
434 1.1 christos *littlenum_pointer = work & LITTLENUM_MASK;
435 1.1 christos carry = work >> LITTLENUM_NUMBER_OF_BITS;
436 1.1 christos }
437 1.1 christos
438 1.1 christos if (carry != 0)
439 1.1 christos {
440 1.1 christos /*
441 1.1 christos * We have a GROSS internal error.
442 1.1 christos * This should never happen.
443 1.1 christos */
444 1.1 christos as_fatal (_("failed sanity check"));
445 1.1 christos }
446 1.1 christos }
447 1.1 christos else
448 1.1 christos {
449 1.1 christos ++count; /* '.' doesn't alter digits used count. */
450 1.1 christos }
451 1.1 christos }
452 1.1 christos
453 1.1 christos /*
454 1.1 christos * Digits_binary_low[] properly encodes the value of the digits.
455 1.1 christos * Forget about any high-order littlenums that are 0.
456 1.1 christos */
457 1.1 christos while (digits_binary_low[size_of_digits_in_littlenums - 1] == 0
458 1.1 christos && size_of_digits_in_littlenums >= 2)
459 1.1 christos size_of_digits_in_littlenums--;
460 1.1 christos
461 1.1 christos digits_flonum.low = digits_binary_low;
462 1.1 christos digits_flonum.high = digits_binary_low + size_of_digits_in_littlenums - 1;
463 1.1 christos digits_flonum.leader = digits_flonum.high;
464 1.1 christos digits_flonum.exponent = 0;
465 1.1 christos /*
466 1.1 christos * The value of digits_flonum . sign should not be important.
467 1.1 christos * We have already decided the output's sign.
468 1.1 christos * We trust that the sign won't influence the other parts of the number!
469 1.1 christos * So we give it a value for these reasons:
470 1.1 christos * (1) courtesy to humans reading/debugging
471 1.1 christos * these numbers so they don't get excited about strange values
472 1.1 christos * (2) in future there may be more meaning attached to sign,
473 1.1 christos * and what was
474 1.1 christos * harmless noise may become disruptive, ill-conditioned (or worse)
475 1.1 christos * input.
476 1.1 christos */
477 1.1 christos digits_flonum.sign = '+';
478 1.1 christos
479 1.1 christos {
480 1.1 christos /*
481 1.6 christos * Compute the mantissa (& exponent) of the power of 10.
482 1.1 christos * If successful, then multiply the power of 10 by the digits
483 1.1 christos * giving return_binary_mantissa and return_binary_exponent.
484 1.1 christos */
485 1.1 christos
486 1.1 christos int decimal_exponent_is_negative;
487 1.1 christos /* This refers to the "-56" in "12.34E-56". */
488 1.1 christos /* FALSE: decimal_exponent is positive (or 0) */
489 1.1 christos /* TRUE: decimal_exponent is negative */
490 1.1 christos FLONUM_TYPE temporary_flonum;
491 1.1 christos unsigned int size_of_power_in_littlenums;
492 1.1 christos unsigned int size_of_power_in_chars;
493 1.1 christos
494 1.1 christos size_of_power_in_littlenums = precision;
495 1.1 christos /* Precision has a built-in fudge factor so we get a few guard bits. */
496 1.1 christos
497 1.1 christos decimal_exponent_is_negative = decimal_exponent < 0;
498 1.1 christos if (decimal_exponent_is_negative)
499 1.1 christos {
500 1.1 christos decimal_exponent = -decimal_exponent;
501 1.1 christos }
502 1.1 christos
503 1.1 christos /* From now on: the decimal exponent is > 0. Its sign is separate. */
504 1.1 christos
505 1.1 christos size_of_power_in_chars = size_of_power_in_littlenums
506 1.1 christos * sizeof (LITTLENUM_TYPE) + 2;
507 1.1 christos
508 1.5 christos power_binary_low = (LITTLENUM_TYPE *) xmalloc (size_of_power_in_chars);
509 1.5 christos temporary_binary_low = (LITTLENUM_TYPE *) xmalloc (size_of_power_in_chars);
510 1.5 christos
511 1.1 christos memset ((char *) power_binary_low, '\0', size_of_power_in_chars);
512 1.1 christos *power_binary_low = 1;
513 1.1 christos power_of_10_flonum.exponent = 0;
514 1.1 christos power_of_10_flonum.low = power_binary_low;
515 1.1 christos power_of_10_flonum.leader = power_binary_low;
516 1.1 christos power_of_10_flonum.high = power_binary_low + size_of_power_in_littlenums - 1;
517 1.1 christos power_of_10_flonum.sign = '+';
518 1.1 christos temporary_flonum.low = temporary_binary_low;
519 1.1 christos temporary_flonum.high = temporary_binary_low + size_of_power_in_littlenums - 1;
520 1.1 christos /*
521 1.1 christos * (power) == 1.
522 1.1 christos * Space for temporary_flonum allocated.
523 1.1 christos */
524 1.1 christos
525 1.1 christos /*
526 1.1 christos * ...
527 1.1 christos *
528 1.1 christos * WHILE more bits
529 1.1 christos * DO find next bit (with place value)
530 1.1 christos * multiply into power mantissa
531 1.1 christos * OD
532 1.1 christos */
533 1.1 christos {
534 1.1 christos int place_number_limit;
535 1.1 christos /* Any 10^(2^n) whose "n" exceeds this */
536 1.1 christos /* value will fall off the end of */
537 1.1 christos /* flonum_XXXX_powers_of_ten[]. */
538 1.1 christos int place_number;
539 1.1 christos const FLONUM_TYPE *multiplicand; /* -> 10^(2^n) */
540 1.1 christos
541 1.1 christos place_number_limit = table_size_of_flonum_powers_of_ten;
542 1.1 christos
543 1.1 christos multiplicand = (decimal_exponent_is_negative
544 1.1 christos ? flonum_negative_powers_of_ten
545 1.1 christos : flonum_positive_powers_of_ten);
546 1.1 christos
547 1.1 christos for (place_number = 1;/* Place value of this bit of exponent. */
548 1.1 christos decimal_exponent;/* Quit when no more 1 bits in exponent. */
549 1.1 christos decimal_exponent >>= 1, place_number++)
550 1.1 christos {
551 1.1 christos if (decimal_exponent & 1)
552 1.1 christos {
553 1.1 christos if (place_number > place_number_limit)
554 1.1 christos {
555 1.1 christos /* The decimal exponent has a magnitude so great
556 1.1 christos that our tables can't help us fragment it.
557 1.1 christos Although this routine is in error because it
558 1.1 christos can't imagine a number that big, signal an
559 1.1 christos error as if it is the user's fault for
560 1.1 christos presenting such a big number. */
561 1.1 christos return_value = ERROR_EXPONENT_OVERFLOW;
562 1.1 christos /* quit out of loop gracefully */
563 1.1 christos decimal_exponent = 0;
564 1.1 christos }
565 1.1 christos else
566 1.1 christos {
567 1.1 christos #ifdef TRACE
568 1.1 christos printf ("before multiply, place_number = %d., power_of_10_flonum:\n",
569 1.1 christos place_number);
570 1.1 christos
571 1.1 christos flonum_print (&power_of_10_flonum);
572 1.1 christos (void) putchar ('\n');
573 1.1 christos #endif
574 1.1 christos #ifdef TRACE
575 1.1 christos printf ("multiplier:\n");
576 1.1 christos flonum_print (multiplicand + place_number);
577 1.1 christos (void) putchar ('\n');
578 1.1 christos #endif
579 1.1 christos flonum_multip (multiplicand + place_number,
580 1.1 christos &power_of_10_flonum, &temporary_flonum);
581 1.1 christos #ifdef TRACE
582 1.1 christos printf ("after multiply:\n");
583 1.1 christos flonum_print (&temporary_flonum);
584 1.1 christos (void) putchar ('\n');
585 1.1 christos #endif
586 1.1 christos flonum_copy (&temporary_flonum, &power_of_10_flonum);
587 1.1 christos #ifdef TRACE
588 1.1 christos printf ("after copy:\n");
589 1.1 christos flonum_print (&power_of_10_flonum);
590 1.1 christos (void) putchar ('\n');
591 1.1 christos #endif
592 1.1 christos } /* If this bit of decimal_exponent was computable.*/
593 1.1 christos } /* If this bit of decimal_exponent was set. */
594 1.1 christos } /* For each bit of binary representation of exponent */
595 1.1 christos #ifdef TRACE
596 1.1 christos printf ("after computing power_of_10_flonum:\n");
597 1.1 christos flonum_print (&power_of_10_flonum);
598 1.1 christos (void) putchar ('\n');
599 1.1 christos #endif
600 1.1 christos }
601 1.1 christos }
602 1.1 christos
603 1.1 christos /*
604 1.1 christos * power_of_10_flonum is power of ten in binary (mantissa) , (exponent).
605 1.1 christos * It may be the number 1, in which case we don't NEED to multiply.
606 1.1 christos *
607 1.1 christos * Multiply (decimal digits) by power_of_10_flonum.
608 1.1 christos */
609 1.1 christos
610 1.1 christos flonum_multip (&power_of_10_flonum, &digits_flonum, address_of_generic_floating_point_number);
611 1.1 christos /* Assert sign of the number we made is '+'. */
612 1.1 christos address_of_generic_floating_point_number->sign = digits_sign_char;
613 1.1 christos
614 1.5 christos if (temporary_binary_low)
615 1.5 christos free (temporary_binary_low);
616 1.5 christos if (power_binary_low)
617 1.5 christos free (power_binary_low);
618 1.5 christos free (digits_binary_low);
619 1.1 christos }
620 1.1 christos return return_value;
621 1.1 christos }
622 1.1 christos
623 1.1 christos #ifdef TRACE
624 1.1 christos static void
625 1.1 christos flonum_print (f)
626 1.1 christos const FLONUM_TYPE *f;
627 1.1 christos {
628 1.1 christos LITTLENUM_TYPE *lp;
629 1.1 christos char littlenum_format[10];
630 1.1 christos sprintf (littlenum_format, " %%0%dx", sizeof (LITTLENUM_TYPE) * 2);
631 1.1 christos #define print_littlenum(LP) (printf (littlenum_format, LP))
632 1.1 christos printf ("flonum @%p %c e%ld", f, f->sign, f->exponent);
633 1.1 christos if (f->low < f->high)
634 1.1 christos for (lp = f->high; lp >= f->low; lp--)
635 1.1 christos print_littlenum (*lp);
636 1.1 christos else
637 1.1 christos for (lp = f->low; lp <= f->high; lp++)
638 1.1 christos print_littlenum (*lp);
639 1.1 christos printf ("\n");
640 1.1 christos fflush (stdout);
641 1.1 christos }
642 1.1 christos #endif
643 1.1 christos
644 1.1 christos /* end of atof_generic.c */
645