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