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