| OLD | NEW |
| 1 /* | 1 /* |
| 2 ********************************************************************** | 2 ********************************************************************** |
| 3 * Copyright (C) 1997-2010, International Business Machines | 3 * Copyright (C) 1997-2010, International Business Machines |
| 4 * Corporation and others. All Rights Reserved. | 4 * Corporation and others. All Rights Reserved. |
| 5 ********************************************************************** | 5 ********************************************************************** |
| 6 * | 6 * |
| 7 * File DIGITLST.CPP | 7 * File DIGITLST.CPP |
| 8 * | 8 * |
| 9 * Modification History: | 9 * Modification History: |
| 10 * | 10 * |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 | 53 |
| 54 static char gDecimal = 0; | 54 static char gDecimal = 0; |
| 55 | 55 |
| 56 /* Only for 32 bit numbers. Ignore the negative sign. */ | 56 /* Only for 32 bit numbers. Ignore the negative sign. */ |
| 57 static const char LONG_MIN_REP[] = "2147483648"; | 57 static const char LONG_MIN_REP[] = "2147483648"; |
| 58 static const char I64_MIN_REP[] = "9223372036854775808"; | 58 static const char I64_MIN_REP[] = "9223372036854775808"; |
| 59 | 59 |
| 60 | 60 |
| 61 U_NAMESPACE_BEGIN | 61 U_NAMESPACE_BEGIN |
| 62 | 62 |
| 63 static void |
| 64 loadDecimalChar() { |
| 65 if (gDecimal == 0) { |
| 66 char rep[MAX_DIGITS]; |
| 67 // For machines that decide to change the decimal on you, |
| 68 // and try to be too smart with localization. |
| 69 // This normally should be just a '.'. |
| 70 sprintf(rep, "%+1.1f", 1.0); |
| 71 gDecimal = rep[2]; |
| 72 } |
| 73 } |
| 74 |
| 63 // ------------------------------------- | 75 // ------------------------------------- |
| 64 // default constructor | 76 // default constructor |
| 65 | 77 |
| 66 DigitList::DigitList() | 78 DigitList::DigitList() |
| 67 { | 79 { |
| 68 uprv_decContextDefault(&fContext, DEC_INIT_BASE); | 80 uprv_decContextDefault(&fContext, DEC_INIT_BASE); |
| 69 fContext.traps = 0; | 81 fContext.traps = 0; |
| 70 uprv_decContextSetRounding(&fContext, DEC_ROUND_HALF_EVEN); | 82 uprv_decContextSetRounding(&fContext, DEC_ROUND_HALF_EVEN); |
| 71 fContext.digits = fStorage.getCapacity(); | 83 fContext.digits = fStorage.getCapacity(); |
| 72 | 84 |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 { | 403 { |
| 392 // TODO: fix thread safety. Can probably be finessed some by analyzing | 404 // TODO: fix thread safety. Can probably be finessed some by analyzing |
| 393 // what public const functions can see which DigitLists. | 405 // what public const functions can see which DigitLists. |
| 394 // Like precompute fDouble for DigitLists coming in from a parse | 406 // Like precompute fDouble for DigitLists coming in from a parse |
| 395 // or from a Formattable::set(), but not for any others. | 407 // or from a Formattable::set(), but not for any others. |
| 396 if (fHaveDouble) { | 408 if (fHaveDouble) { |
| 397 return fDouble; | 409 return fDouble; |
| 398 } | 410 } |
| 399 DigitList *nonConstThis = const_cast<DigitList *>(this); | 411 DigitList *nonConstThis = const_cast<DigitList *>(this); |
| 400 | 412 |
| 401 if (gDecimal == 0) { | |
| 402 char rep[MAX_DIGITS]; | |
| 403 // For machines that decide to change the decimal on you, | |
| 404 // and try to be too smart with localization. | |
| 405 // This normally should be just a '.'. | |
| 406 sprintf(rep, "%+1.1f", 1.0); | |
| 407 gDecimal = rep[2]; | |
| 408 } | |
| 409 | |
| 410 if (isZero()) { | 413 if (isZero()) { |
| 411 nonConstThis->fDouble = 0.0; | 414 nonConstThis->fDouble = 0.0; |
| 412 if (decNumberIsNegative(fDecNumber)) { | 415 if (decNumberIsNegative(fDecNumber)) { |
| 413 nonConstThis->fDouble /= -1; | 416 nonConstThis->fDouble /= -1; |
| 414 } | 417 } |
| 415 } else if (isInfinite()) { | 418 } else if (isInfinite()) { |
| 416 if (std::numeric_limits<double>::has_infinity) { | 419 if (std::numeric_limits<double>::has_infinity) { |
| 417 nonConstThis->fDouble = std::numeric_limits<double>::infinity(); | 420 nonConstThis->fDouble = std::numeric_limits<double>::infinity(); |
| 418 } else { | 421 } else { |
| 419 nonConstThis->fDouble = std::numeric_limits<double>::max(); | 422 nonConstThis->fDouble = std::numeric_limits<double>::max(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 434 DigitList numToConvert(*this); | 437 DigitList numToConvert(*this); |
| 435 numToConvert.reduce(); // Removes any trailing zeros, so that dig
it count is good. | 438 numToConvert.reduce(); // Removes any trailing zeros, so that dig
it count is good. |
| 436 numToConvert.round(MAX_DBL_DIGITS+3); | 439 numToConvert.round(MAX_DBL_DIGITS+3); |
| 437 uprv_decNumberToString(numToConvert.fDecNumber, s); | 440 uprv_decNumberToString(numToConvert.fDecNumber, s); |
| 438 // TODO: how many extra digits should be included for an accurate c
onversion? | 441 // TODO: how many extra digits should be included for an accurate c
onversion? |
| 439 } else { | 442 } else { |
| 440 uprv_decNumberToString(this->fDecNumber, s); | 443 uprv_decNumberToString(this->fDecNumber, s); |
| 441 } | 444 } |
| 442 U_ASSERT(uprv_strlen(&s[0]) < MAX_DBL_DIGITS+18); | 445 U_ASSERT(uprv_strlen(&s[0]) < MAX_DBL_DIGITS+18); |
| 443 | 446 |
| 447 loadDecimalChar(); |
| 444 if (gDecimal != '.') { | 448 if (gDecimal != '.') { |
| 445 char *decimalPt = strchr(s, '.'); | 449 char *decimalPt = strchr(s, '.'); |
| 446 if (decimalPt != NULL) { | 450 if (decimalPt != NULL) { |
| 447 *decimalPt = gDecimal; | 451 *decimalPt = gDecimal; |
| 448 } | 452 } |
| 449 } | 453 } |
| 450 char *end = NULL; | 454 char *end = NULL; |
| 451 nonConstThis->fDouble = uprv_strtod(s, &end); | 455 nonConstThis->fDouble = uprv_strtod(s, &end); |
| 452 } | 456 } |
| 453 nonConstThis->fHaveDouble = TRUE; | 457 nonConstThis->fHaveDouble = TRUE; |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 720 void | 724 void |
| 721 DigitList::set(double source) | 725 DigitList::set(double source) |
| 722 { | 726 { |
| 723 // for now, simple implementation; later, do proper IEEE stuff | 727 // for now, simple implementation; later, do proper IEEE stuff |
| 724 char rep[MAX_DIGITS + 8]; // Extra space for '+', '.', e+NNN, and '\0' (actu
ally +8 is enough) | 728 char rep[MAX_DIGITS + 8]; // Extra space for '+', '.', e+NNN, and '\0' (actu
ally +8 is enough) |
| 725 | 729 |
| 726 // Generate a representation of the form /[+-][0-9]+e[+-][0-9]+/ | 730 // Generate a representation of the form /[+-][0-9]+e[+-][0-9]+/ |
| 727 sprintf(rep, "%+1.*e", MAX_DBL_DIGITS - 1, source); | 731 sprintf(rep, "%+1.*e", MAX_DBL_DIGITS - 1, source); |
| 728 U_ASSERT(uprv_strlen(rep) < sizeof(rep)); | 732 U_ASSERT(uprv_strlen(rep) < sizeof(rep)); |
| 729 | 733 |
| 734 // uprv_decNumberFromString() will parse the string expecting '.' as a |
| 735 // decimal separator, however sprintf() can use ',' in certain locales. |
| 736 // Overwrite a different decimal separator with '.' here before proceeding. |
| 737 loadDecimalChar(); |
| 738 if (gDecimal != '.') { |
| 739 char *decimalPt = strchr(rep, gDecimal); |
| 740 if (decimalPt != NULL) { |
| 741 *decimalPt = '.'; |
| 742 } |
| 743 } |
| 744 |
| 730 // Create a decNumber from the string. | 745 // Create a decNumber from the string. |
| 731 uprv_decNumberFromString(fDecNumber, rep, &fContext); | 746 uprv_decNumberFromString(fDecNumber, rep, &fContext); |
| 732 uprv_decNumberTrim(fDecNumber); | 747 uprv_decNumberTrim(fDecNumber); |
| 733 fDouble = source; | 748 fDouble = source; |
| 734 fHaveDouble = TRUE; | 749 fHaveDouble = TRUE; |
| 735 } | 750 } |
| 736 | 751 |
| 737 // ------------------------------------- | 752 // ------------------------------------- |
| 738 | 753 |
| 739 /* | 754 /* |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 852 DigitList::isZero() const | 867 DigitList::isZero() const |
| 853 { | 868 { |
| 854 return decNumberIsZero(fDecNumber); | 869 return decNumberIsZero(fDecNumber); |
| 855 } | 870 } |
| 856 | 871 |
| 857 | 872 |
| 858 U_NAMESPACE_END | 873 U_NAMESPACE_END |
| 859 #endif // #if !UCONFIG_NO_FORMATTING | 874 #endif // #if !UCONFIG_NO_FORMATTING |
| 860 | 875 |
| 861 //eof | 876 //eof |
| OLD | NEW |