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 loadDecimalChar(); | |
735 if (gDecimal != '.') { | |
736 char *decimalPt = strchr(rep, gDecimal); | |
737 if (decimalPt != NULL) { | |
738 *decimalPt = '.'; | |
jungshik at Google
2011/06/07 21:41:30
nit: can you add a comment explaining why you need
Joao da Silva
2011/06/08 11:37:43
Done.
| |
739 } | |
740 } | |
741 | |
730 // Create a decNumber from the string. | 742 // Create a decNumber from the string. |
731 uprv_decNumberFromString(fDecNumber, rep, &fContext); | 743 uprv_decNumberFromString(fDecNumber, rep, &fContext); |
732 uprv_decNumberTrim(fDecNumber); | 744 uprv_decNumberTrim(fDecNumber); |
733 fDouble = source; | 745 fDouble = source; |
734 fHaveDouble = TRUE; | 746 fHaveDouble = TRUE; |
735 } | 747 } |
736 | 748 |
737 // ------------------------------------- | 749 // ------------------------------------- |
738 | 750 |
739 /* | 751 /* |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
852 DigitList::isZero() const | 864 DigitList::isZero() const |
853 { | 865 { |
854 return decNumberIsZero(fDecNumber); | 866 return decNumberIsZero(fDecNumber); |
855 } | 867 } |
856 | 868 |
857 | 869 |
858 U_NAMESPACE_END | 870 U_NAMESPACE_END |
859 #endif // #if !UCONFIG_NO_FORMATTING | 871 #endif // #if !UCONFIG_NO_FORMATTING |
860 | 872 |
861 //eof | 873 //eof |
OLD | NEW |