Changeset 5ee9692 in mainline for uspace/lib/posix/stdlib/strtold.c
- Timestamp:
- 2011-06-19T13:23:54Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 918e236f
- Parents:
- 63fc519
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/posix/stdlib/strtold.c
r63fc519 r5ee9692 53 53 #endif 54 54 55 // TODO: documentation55 // TODO: clean up, documentation 56 56 57 57 // FIXME: ensure it builds and works on all platforms … … 238 238 /* digits before decimal point */ 239 239 while (isdigit(str[i])) { 240 if (parsed_digits < PARSE_DECIMAL_DIGS) { 240 if (parsed_digits == 0 && str[i] == '0') { 241 /* Nothing, just skip leading zeros. */ 242 } else if (parsed_digits < PARSE_DECIMAL_DIGS) { 241 243 significand *= DEC_BASE; 242 244 significand += str[i] - '0'; … … 254 256 /* digits after decimal point */ 255 257 while (isdigit(str[i])) { 256 if (parsed_digits < PARSE_DECIMAL_DIGS) { 258 if (parsed_digits == 0 && str[i] == '0') { 259 /* Skip leading zeros and decrement exponent. */ 260 exponent--; 261 } else if (parsed_digits < PARSE_DECIMAL_DIGS) { 257 262 significand *= DEC_BASE; 258 263 significand += str[i] - '0'; … … 282 287 } 283 288 284 while (isdigit(str[i]) ) {289 while (isdigit(str[i]) && exp < 65536) { 285 290 exp *= DEC_BASE; 286 291 exp += str[i] - '0'; … … 306 311 } 307 312 308 static inline int hex_value(char ch) { 313 static inline int hex_value(char ch) 314 { 309 315 if (ch <= '9') { 310 316 return ch - '0'; … … 312 318 return 10 + tolower(ch) - 'a'; 313 319 } 320 } 321 322 /** 323 * @param val Integer value. 324 * @return How many leading zero bits there are. (Maximum is 3) 325 */ 326 static inline int leading_zeros(uint64_t val) 327 { 328 for (int i = 3; i > 0; --i) { 329 if ((val >> (64 - i)) == 0) { 330 return i; 331 } 332 } 333 334 return 0; 314 335 } 315 336 … … 345 366 /* digits before decimal point */ 346 367 while (posix_isxdigit(str[i])) { 347 if (parsed_digits < PARSE_HEX_DIGS) { 368 if (parsed_digits == 0 && str[i] == '0') { 369 /* Nothing, just skip leading zeros. */ 370 } else if (parsed_digits < PARSE_HEX_DIGS) { 348 371 significand *= HEX_BASE; 349 372 significand += hex_value(str[i]); 350 373 parsed_digits++; 374 } else if (parsed_digits == PARSE_HEX_DIGS) { 375 /* The first digit may have had leading zeros, 376 * so we need to parse one more digit and shift 377 * the value accordingly. 378 */ 379 380 int zeros = leading_zeros(significand); 381 significand = (significand << zeros) | 382 (hex_value(str[i]) >> (4 - zeros)); 383 384 exponent += (4 - zeros); 385 parsed_digits++; 351 386 } else { 352 387 exponent += 4; … … 361 396 /* digits after decimal point */ 362 397 while (posix_isxdigit(str[i])) { 363 if (parsed_digits < PARSE_HEX_DIGS) { 398 if (parsed_digits == 0 && str[i] == '0') { 399 /* Skip leading zeros and decrement exponent. */ 400 exponent -= 4; 401 } else if (parsed_digits < PARSE_HEX_DIGS) { 364 402 significand *= HEX_BASE; 365 403 significand += hex_value(str[i]); 366 404 exponent -= 4; 405 parsed_digits++; 406 } else if (parsed_digits == PARSE_HEX_DIGS) { 407 /* The first digit may have had leading zeros, 408 * so we need to parse one more digit and shift 409 * the value accordingly. 410 */ 411 412 int zeros = leading_zeros(significand); 413 significand = (significand << zeros) | 414 (hex_value(str[i]) >> (4 - zeros)); 415 416 exponent -= zeros; 367 417 parsed_digits++; 368 418 } else { … … 389 439 } 390 440 391 while (isdigit(str[i]) ) {441 while (isdigit(str[i]) && exp < 65536) { 392 442 exp *= DEC_BASE; 393 443 exp += str[i] - '0';
Note:
See TracChangeset
for help on using the changeset viewer.