|
|
1.1.1.2 ! root 1: /* atof_generic.c - turn a string of digits into a Flonum ! 2: Copyright (C) 1987 Free Software Foundation, Inc. 1.1 root 3: 1.1.1.2 ! root 4: This file is part of GAS, the GNU Assembler. 1.1 root 5: 1.1.1.2 ! root 6: GAS is free software; you can redistribute it and/or modify ! 7: it under the terms of the GNU General Public License as published by ! 8: the Free Software Foundation; either version 1, or (at your option) ! 9: any later version. ! 10: ! 11: GAS is distributed in the hope that it will be useful, ! 12: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: GNU General Public License for more details. ! 15: ! 16: You should have received a copy of the GNU General Public License ! 17: along with GAS; see the file COPYING. If not, write to ! 18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 1.1 root 19: 20: #include <ctype.h> 21: #include "flonum.h" 1.1.1.2 ! root 22: #ifdef __GNUC__ ! 23: #define alloca __builtin_alloca ! 24: #else 1.1 root 25: #ifdef sparc 26: #include <alloca.h> 27: #endif 1.1.1.2 ! root 28: #endif ! 29: ! 30: #ifdef USG ! 31: #define bzero(s,n) memset(s,0,n) ! 32: #define index strchr ! 33: #endif 1.1 root 34: 35: #define FALSE (0) 36: #define TRUE (1) 37: 38: char *index(); 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 int * 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: <optional-exponent> ::= {empty} | <exponent-character> <optional-sign> <integer> 67: <integer> ::= <digit> | <digit> <integer> 68: <digit> ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' 69: <exponent-character> ::= {one character from "string_of_decimal_exponent_marks"} 70: <radix-character> ::= {one character from "string_of_decimal_marks"} 71: 72: */ 73: 74: int /* 0 if OK */ 75: 76: atof_generic ( 77: address_of_string_pointer, /* return pointer to just AFTER number we read. */ 78: string_of_decimal_marks, /* At most one per number. */ 79: string_of_decimal_exponent_marks, 80: address_of_generic_floating_point_number) 81: 82: char * * address_of_string_pointer; 83: char * string_of_decimal_marks; 84: char * string_of_decimal_exponent_marks; 85: FLONUM_TYPE * address_of_generic_floating_point_number; 86: 87: { 88: 89: int return_value; /* 0 means OK. */ 90: char * first_digit; 91: /* char * last_digit; JF unused */ 92: int number_of_digits_before_decimal; 93: int number_of_digits_after_decimal; 94: long int decimal_exponent; 95: int number_of_digits_available; 96: char digits_sign_char; 97: 98: { 99: /* 100: * Scan the input string, abstracting (1)digits (2)decimal mark (3) exponent. 101: * It would be simpler to modify the string, but we don't; just to be nice 102: * to caller. 103: * We need to know how many digits we have, so we can allocate space for 104: * the digits' value. 105: */ 106: 107: char * p; 108: char c; 109: int seen_significant_digit; 110: 111: first_digit = * address_of_string_pointer; 112: c= *first_digit; 1.1.1.2 ! root 113: if(c=='n' && first_digit[1]=='a' && first_digit[2]=='n') { ! 114: address_of_generic_floating_point_number->sign=0; ! 115: address_of_generic_floating_point_number->exponent=0; ! 116: address_of_generic_floating_point_number->leader=address_of_generic_floating_point_number->low; ! 117: (*address_of_string_pointer)+=3; ! 118: return 0; ! 119: } ! 120: if(c=='i' && first_digit[1]=='n' && first_digit[2]=='f') { ! 121: address_of_generic_floating_point_number->sign='P'; ! 122: address_of_generic_floating_point_number->exponent=0; ! 123: address_of_generic_floating_point_number->leader=address_of_generic_floating_point_number->low; ! 124: (*address_of_string_pointer)+=3; ! 125: return 0; ! 126: } 1.1 root 127: if (c=='-' || c=='+') 128: { 1.1.1.2 ! root 129: if(first_digit[1]=='i' && first_digit[2]=='n' && first_digit[3]=='f') { ! 130: address_of_generic_floating_point_number->sign = (c=='+') ? 'P' : 'N'; ! 131: address_of_generic_floating_point_number->exponent=0; ! 132: address_of_generic_floating_point_number->leader=address_of_generic_floating_point_number->low; ! 133: (*address_of_string_pointer)+=4; ! 134: return 0; ! 135: } 1.1 root 136: digits_sign_char = c; 137: first_digit ++; 138: } 139: else 140: { 141: digits_sign_char = '+'; 142: } 143: number_of_digits_before_decimal = 0; 144: number_of_digits_after_decimal = 0; 145: decimal_exponent = 0; 146: seen_significant_digit = FALSE; 147: for (p = first_digit; 148: (c = * p) 149: && (!c || ! index (string_of_decimal_marks, c) ) 150: && (!c || ! index (string_of_decimal_exponent_marks, c) ); 151: p ++) 152: { 153: if (isdigit(c)) 154: { 155: if (seen_significant_digit || c > '0') 156: { 157: number_of_digits_before_decimal ++; 158: seen_significant_digit = TRUE; 159: } 160: else 161: { 162: first_digit++; 163: } 164: } 165: else 166: { 167: break; /* p -> char after pre-decimal digits. */ 168: } 169: } /* For each digit before decimal mark. */ 170: if (c && index (string_of_decimal_marks, c)) 171: { 172: for (p ++; 173: (c = * p) 174: && (!c || ! index (string_of_decimal_exponent_marks, c) ); 175: p ++) 176: { 177: if (isdigit(c)) 178: { 179: number_of_digits_after_decimal ++; /* This may be retracted below. */ 180: if (/* seen_significant_digit || */ c > '0') 181: { 182: seen_significant_digit = TRUE; 183: } 184: } 185: else 186: { 187: if ( ! seen_significant_digit) 188: { 189: number_of_digits_after_decimal = 0; 190: } 191: break; 192: } 193: } /* For each digit after decimal mark. */ 194: } 195: /* last_digit = p; JF unused */ 196: 197: if (c && index (string_of_decimal_exponent_marks, c) ) 198: { 199: char digits_exponent_sign_char; 200: 201: c = * ++ p; 202: if (c && index ("+-",c)) 203: { 204: digits_exponent_sign_char = c; 205: c = * ++ p; 206: } 207: else 208: { 209: digits_exponent_sign_char = '+'; 210: } 211: for (; 212: (c); 213: c = * ++ p) 214: { 215: if (isdigit(c)) 216: { 217: decimal_exponent = decimal_exponent * 10 + c - '0'; 218: /* 219: * BUG! If we overflow here, we lose! 220: */ 221: } 222: else 223: { 224: break; 225: } 226: } 227: if (digits_exponent_sign_char == '-') 228: { 229: decimal_exponent = - decimal_exponent; 230: } 231: } 232: * address_of_string_pointer = p; 233: } 234: 235: number_of_digits_available = 236: number_of_digits_before_decimal 237: + number_of_digits_after_decimal; 238: return_value = 0; 239: if (number_of_digits_available == 0) 240: { 241: address_of_generic_floating_point_number -> exponent = 0; /* Not strictly necessary */ 242: address_of_generic_floating_point_number -> leader 243: = -1 + address_of_generic_floating_point_number -> low; 244: address_of_generic_floating_point_number -> sign = digits_sign_char; 245: /* We have just concocted (+/-)0.0E0 */ 246: } 247: else 248: { 249: LITTLENUM_TYPE * digits_binary_low; 250: int precision; 251: int maximum_useful_digits; 252: int number_of_digits_to_use; 253: int more_than_enough_bits_for_digits; 254: int more_than_enough_littlenums_for_digits; 255: int size_of_digits_in_littlenums; 256: int size_of_digits_in_chars; 257: FLONUM_TYPE power_of_10_flonum; 258: FLONUM_TYPE digits_flonum; 259: 260: 261: precision = (address_of_generic_floating_point_number -> high 262: - address_of_generic_floating_point_number -> low 263: + 1 264: ) /* Number of destination littlenums. */ 265: + 2; /* + 2 :: guard bits :: excess precision */ 266: maximum_useful_digits = ( ((double) (precision - 2)) 267: * ((double) (LITTLENUM_NUMBER_OF_BITS)) 268: / (LOG_TO_BASE_2_OF_10) 269: ) 270: + 2; /* 2 :: guard digits. */ 271: if (number_of_digits_available > maximum_useful_digits) 272: { 273: number_of_digits_to_use = maximum_useful_digits; 274: } 275: else 276: { 277: number_of_digits_to_use = number_of_digits_available; 278: } 279: decimal_exponent += number_of_digits_before_decimal - number_of_digits_to_use; 280: 281: more_than_enough_bits_for_digits 282: = ((((double)number_of_digits_to_use) * LOG_TO_BASE_2_OF_10) + 1); 283: more_than_enough_littlenums_for_digits 284: = ( more_than_enough_bits_for_digits 285: / LITTLENUM_NUMBER_OF_BITS 286: ) 287: + 2; 288: 289: /* 290: * Compute (digits) part. In "12.34E56" this is the "1234" part. 291: * Arithmetic is exact here. If no digits are supplied then 292: * this part is a 0 valued binary integer. 293: * Allocate room to build up the binary number as littlenums. 294: * We want this memory to disappear when we leave this function. 295: * Assume no alignment problems => (room for n objects) == 296: * n * (room for 1 object). 297: */ 298: 299: size_of_digits_in_littlenums = more_than_enough_littlenums_for_digits; 300: size_of_digits_in_chars = size_of_digits_in_littlenums 301: * sizeof( LITTLENUM_TYPE ); 302: digits_binary_low = (LITTLENUM_TYPE *) 303: alloca (size_of_digits_in_chars); 304: bzero ((char *)digits_binary_low, size_of_digits_in_chars); 305: 306: /* Digits_binary_low[] is allocated and zeroed. */ 307: 308: { 309: /* 310: * Parse the decimal digits as if * digits_low was in the units position. 311: * Emit a binary number into digits_binary_low[]. 312: * 313: * Use a large-precision version of: 314: * (((1st-digit) * 10 + 2nd-digit) * 10 + 3rd-digit ...) * 10 + last-digit 315: */ 316: 317: char * p; 318: char c; 319: int count; /* Number of useful digits left to scan. */ 320: 321: for (p = first_digit, count = number_of_digits_to_use; 322: count; 323: p ++, -- count) 324: { 325: c = * p; 326: if (isdigit(c)) 327: { 328: /* 329: * Multiply by 10. Assume can never overflow. 330: * Add this digit to digits_binary_low[]. 331: */ 332: 333: long int carry; 334: LITTLENUM_TYPE * littlenum_pointer; 335: LITTLENUM_TYPE * littlenum_limit; 336: 337: littlenum_limit 338: = digits_binary_low 339: + more_than_enough_littlenums_for_digits 340: - 1; 341: carry = c - '0'; /* char -> binary */ 342: for (littlenum_pointer = digits_binary_low; 343: littlenum_pointer <= littlenum_limit; 344: littlenum_pointer ++) 345: { 346: long int work; 347: 1.1.1.2 ! root 348: work = carry + 10 * (long)(*littlenum_pointer); 1.1 root 349: * littlenum_pointer = work & LITTLENUM_MASK; 350: carry = work >> LITTLENUM_NUMBER_OF_BITS; 351: } 352: if (carry != 0) 353: { 354: /* 355: * We have a GROSS internal error. 356: * This should never happen. 357: */ 358: abort(); /* RMS prefers abort() to any message. */ 359: } 360: } 361: else 362: { 363: ++ count; /* '.' doesn't alter digits used count. */ 364: } /* if valid digit */ 365: } /* for each digit */ 366: } 367: 368: /* 369: * Digits_binary_low[] properly encodes the value of the digits. 370: * Forget about any high-order littlenums that are 0. 371: */ 372: while (digits_binary_low [size_of_digits_in_littlenums - 1] == 0) 373: { 374: size_of_digits_in_littlenums --; 375: } 376: 377: digits_flonum . low = digits_binary_low; 378: digits_flonum . high = digits_binary_low + size_of_digits_in_littlenums - 1; 379: digits_flonum . leader = digits_flonum . high; 380: digits_flonum . exponent = 0; 381: /* 382: * The value of digits_flonum . sign should not be important. 383: * We have already decided th output's sign. 384: * We trust that the sign won't influence the other parts of the number! 385: * So we give it a value for these reasons: 386: * (1) courtesy to humans reading/debugging 387: * these numbers so they don't get excited about strange values 388: * (2) in future there may be more meaning attached to sign, 389: * and what was 390: * harmless noise may become disruptive, ill-conditioned (or worse) 391: * input. 392: */ 393: digits_flonum . sign = '+'; 394: 395: { 396: /* 397: * Compute the mantssa (& exponent) of the power of 10. 398: * If sucessful, then multiply the power of 10 by the digits 399: * giving return_binary_mantissa and return_binary_exponent. 400: */ 401: 402: LITTLENUM_TYPE *power_binary_low; 403: int decimal_exponent_is_negative; 404: /* This refers to the "-56" in "12.34E-56". */ 405: /* FALSE: decimal_exponent is positive (or 0) */ 406: /* TRUE: decimal_exponent is negative */ 407: FLONUM_TYPE temporary_flonum; 408: LITTLENUM_TYPE *temporary_binary_low; 409: int size_of_power_in_littlenums; 410: int size_of_power_in_chars; 411: 412: size_of_power_in_littlenums = precision; 413: /* Precision has a built-in fudge factor so we get a few guard bits. */ 414: 415: 416: decimal_exponent_is_negative = decimal_exponent < 0; 417: if (decimal_exponent_is_negative) 418: { 419: decimal_exponent = - decimal_exponent; 420: } 421: /* From now on: the decimal exponent is > 0. Its sign is seperate. */ 422: 423: size_of_power_in_chars 424: = size_of_power_in_littlenums 425: * sizeof( LITTLENUM_TYPE ); 426: power_binary_low = (LITTLENUM_TYPE *) alloca ( size_of_power_in_chars ); 427: temporary_binary_low = (LITTLENUM_TYPE *) alloca ( size_of_power_in_chars ); 428: bzero ((char *)power_binary_low, size_of_power_in_chars); 429: * power_binary_low = 1; 430: power_of_10_flonum . exponent = 0; 431: power_of_10_flonum . low = power_binary_low; 432: power_of_10_flonum . leader = power_binary_low; 433: power_of_10_flonum . high = power_binary_low + size_of_power_in_littlenums - 1; 434: power_of_10_flonum . sign = '+'; 435: temporary_flonum . low = temporary_binary_low; 436: temporary_flonum . high = temporary_binary_low + size_of_power_in_littlenums - 1; 437: /* 438: * (power) == 1. 439: * Space for temporary_flonum allocated. 440: */ 441: 442: /* 443: * ... 444: * 445: * WHILE more bits 446: * DO find next bit (with place value) 447: * multiply into power mantissa 448: * OD 449: */ 450: { 451: int place_number_limit; 452: /* Any 10^(2^n) whose "n" exceeds this */ 453: /* value will fall off the end of */ 454: /* flonum_XXXX_powers_of_ten[]. */ 455: int place_number; 456: FLONUM_TYPE * multiplicand; /* -> 10^(2^n) */ 457: 458: place_number_limit = table_size_of_flonum_powers_of_ten; 459: multiplicand 460: = ( decimal_exponent_is_negative 461: ? flonum_negative_powers_of_ten 462: : flonum_positive_powers_of_ten); 463: for (place_number = 1; /* Place value of this bit of exponent. */ 464: decimal_exponent; /* Quit when no more 1 bits in exponent. */ 465: decimal_exponent >>= 1 466: , place_number ++) 467: { 468: if (decimal_exponent & 1) 469: { 470: if (place_number > place_number_limit) 471: { 472: /* 473: * The decimal exponent has a magnitude so great that 474: * our tables can't help us fragment it. Although this 475: * routine is in error because it can't imagine a 476: * number that big, signal an error as if it is the 477: * user's fault for presenting such a big number. 478: */ 479: return_value = ERROR_EXPONENT_OVERFLOW; 480: /* 481: * quit out of loop gracefully 482: */ 483: decimal_exponent = 0; 484: } 485: else 486: { 487: #ifdef TRACE 488: printf("before multiply, place_number = %d., power_of_10_flonum:\n", place_number); 489: flonum_print( & power_of_10_flonum ); 490: (void)putchar('\n'); 491: #endif 492: flonum_multip (multiplicand + place_number, & power_of_10_flonum, & temporary_flonum); 493: flonum_copy (& temporary_flonum, & power_of_10_flonum); 494: } /* If this bit of decimal_exponent was computable.*/ 495: } /* If this bit of decimal_exponent was set. */ 496: } /* For each bit of binary representation of exponent */ 497: #ifdef TRACE 498: printf( " after computing power_of_10_flonum: " ); 499: flonum_print( & power_of_10_flonum ); 500: (void)putchar('\n'); 501: #endif 502: } 503: 504: } 505: 506: /* 507: * power_of_10_flonum is power of ten in binary (mantissa) , (exponent). 508: * It may be the number 1, in which case we don't NEED to multiply. 509: * 510: * Multiply (decimal digits) by power_of_10_flonum. 511: */ 512: 513: flonum_multip (& power_of_10_flonum, & digits_flonum, address_of_generic_floating_point_number); 514: /* Assert sign of the number we made is '+'. */ 515: address_of_generic_floating_point_number -> sign = digits_sign_char; 516: 517: } /* If we had any significant digits. */ 518: return (return_value); 519: } /* atof_generic () */ 520: 521: /* end: atof_generic.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.