| OLD | NEW |
| 1 /* | 1 /* |
| 2 ********************************************************************** | 2 ********************************************************************** |
| 3 * Copyright (C) 1997-2014, International Business Machines | 3 * Copyright (C) 1997-2015, 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 * |
| 11 * Date Name Description | 11 * Date Name Description |
| 12 * 03/21/97 clhuang Converted from java. | 12 * 03/21/97 clhuang Converted from java. |
| 13 * 03/21/97 clhuang Implemented with new APIs. | 13 * 03/21/97 clhuang Implemented with new APIs. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 27 #include "digitlst.h" | 27 #include "digitlst.h" |
| 28 | 28 |
| 29 #if !UCONFIG_NO_FORMATTING | 29 #if !UCONFIG_NO_FORMATTING |
| 30 #include "unicode/putil.h" | 30 #include "unicode/putil.h" |
| 31 #include "charstr.h" | 31 #include "charstr.h" |
| 32 #include "cmemory.h" | 32 #include "cmemory.h" |
| 33 #include "cstring.h" | 33 #include "cstring.h" |
| 34 #include "mutex.h" | 34 #include "mutex.h" |
| 35 #include "putilimp.h" | 35 #include "putilimp.h" |
| 36 #include "uassert.h" | 36 #include "uassert.h" |
| 37 #include "digitinterval.h" |
| 37 #include <stdlib.h> | 38 #include <stdlib.h> |
| 38 #include <limits.h> | 39 #include <limits.h> |
| 39 #include <string.h> | 40 #include <string.h> |
| 40 #include <stdio.h> | 41 #include <stdio.h> |
| 41 #include <limits> | 42 #include <limits> |
| 42 | 43 |
| 43 // *************************************************************************** | 44 // *************************************************************************** |
| 44 // class DigitList | 45 // class DigitList |
| 45 // A wrapper onto decNumber. | 46 // A wrapper onto decNumber. |
| 46 // Used to be standalone. | 47 // Used to be standalone. |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 fDecNumber->digits++; | 390 fDecNumber->digits++; |
| 390 // DigitList emulation - appending doesn't change the magnitude of e
xisting | 391 // DigitList emulation - appending doesn't change the magnitude of e
xisting |
| 391 // digits. With decNumber's decimal being aft
er the | 392 // digits. With decNumber's decimal being aft
er the |
| 392 // least signficant digit, we need to adjust t
he exponent. | 393 // least signficant digit, we need to adjust t
he exponent. |
| 393 fDecNumber->exponent--; | 394 fDecNumber->exponent--; |
| 394 } | 395 } |
| 395 } | 396 } |
| 396 internalClear(); | 397 internalClear(); |
| 397 } | 398 } |
| 398 | 399 |
| 400 char DigitList::getStrtodDecimalSeparator() { |
| 401 // TODO: maybe use andy's pthread once. |
| 402 static char gDecimal = 0; |
| 403 char result; |
| 404 { |
| 405 Mutex mutex; |
| 406 result = gDecimal;; |
| 407 if (result == 0) { |
| 408 // We need to know the decimal separator character that will be used
with strtod(). |
| 409 // Depends on the C runtime global locale. |
| 410 // Most commonly is '.' |
| 411 // TODO: caching could fail if the global locale is changed on the f
ly. |
| 412 char rep[MAX_DIGITS]; |
| 413 sprintf(rep, "%+1.1f", 1.0); |
| 414 result = rep[2]; |
| 415 gDecimal = result;; |
| 416 } |
| 417 } |
| 418 return result; |
| 419 } |
| 420 |
| 399 // ------------------------------------- | 421 // ------------------------------------- |
| 400 | 422 |
| 401 /** | 423 /** |
| 402 * Currently, getDouble() depends on strtod() to do its conversion. | 424 * Currently, getDouble() depends on strtod() to do its conversion. |
| 403 * | 425 * |
| 404 * WARNING!! | 426 * WARNING!! |
| 405 * This is an extremely costly function. ~1/2 of the conversion time | 427 * This is an extremely costly function. ~1/2 of the conversion time |
| 406 * can be linked to this function. | 428 * can be linked to this function. |
| 407 */ | 429 */ |
| 408 double | 430 double |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 | 507 |
| 486 // ------------------------------------- | 508 // ------------------------------------- |
| 487 | 509 |
| 488 /** | 510 /** |
| 489 * convert this number to an int32_t. Round if there is a fractional part. | 511 * convert this number to an int32_t. Round if there is a fractional part. |
| 490 * Return zero if the number cannot be represented. | 512 * Return zero if the number cannot be represented. |
| 491 */ | 513 */ |
| 492 int32_t DigitList::getLong() /*const*/ | 514 int32_t DigitList::getLong() /*const*/ |
| 493 { | 515 { |
| 494 int32_t result = 0; | 516 int32_t result = 0; |
| 495 if (fDecNumber->digits + fDecNumber->exponent > 10) { | 517 if (getUpperExponent() > 10) { |
| 496 // Overflow, absolute value too big. | 518 // Overflow, absolute value too big. |
| 497 return result; | 519 return result; |
| 498 } | 520 } |
| 499 if (fDecNumber->exponent != 0) { | 521 if (fDecNumber->exponent != 0) { |
| 500 // Force to an integer, with zero exponent, rounding if necessary. | 522 // Force to an integer, with zero exponent, rounding if necessary. |
| 501 // (decNumberToInt32 will only work if the exponent is exactly zero.) | 523 // (decNumberToInt32 will only work if the exponent is exactly zero.) |
| 502 DigitList copy(*this); | 524 DigitList copy(*this); |
| 503 DigitList zero; | 525 DigitList zero; |
| 504 uprv_decNumberQuantize(copy.fDecNumber, copy.fDecNumber, zero.fDecNumber
, &fContext); | 526 uprv_decNumberQuantize(copy.fDecNumber, copy.fDecNumber, zero.fDecNumber
, &fContext); |
| 505 result = uprv_decNumberToInt32(copy.fDecNumber, &fContext); | 527 result = uprv_decNumberToInt32(copy.fDecNumber, &fContext); |
| 506 } else { | 528 } else { |
| 507 result = uprv_decNumberToInt32(fDecNumber, &fContext); | 529 result = uprv_decNumberToInt32(fDecNumber, &fContext); |
| 508 } | 530 } |
| 509 return result; | 531 return result; |
| 510 } | 532 } |
| 511 | 533 |
| 512 | 534 |
| 513 /** | 535 /** |
| 514 * convert this number to an int64_t. Truncate if there is a fractional part. | 536 * convert this number to an int64_t. Truncate if there is a fractional part. |
| 515 * Return zero if the number cannot be represented. | 537 * Return zero if the number cannot be represented. |
| 516 */ | 538 */ |
| 517 int64_t DigitList::getInt64() /*const*/ { | 539 int64_t DigitList::getInt64() /*const*/ { |
| 518 if(fHave==kInt64) { | 540 if(fHave==kInt64) { |
| 519 return fUnion.fInt64; | 541 return fUnion.fInt64; |
| 520 } | 542 } |
| 521 // Truncate if non-integer. | 543 // Truncate if non-integer. |
| 522 // Return 0 if out of range. | 544 // Return 0 if out of range. |
| 523 // Range of in64_t is -9223372036854775808 to 9223372036854775807 (19 digit
s) | 545 // Range of in64_t is -9223372036854775808 to 9223372036854775807 (19 digit
s) |
| 524 // | 546 // |
| 525 if (fDecNumber->digits + fDecNumber->exponent > 19) { | 547 if (getUpperExponent() > 19) { |
| 526 // Overflow, absolute value too big. | 548 // Overflow, absolute value too big. |
| 527 return 0; | 549 return 0; |
| 528 } | 550 } |
| 529 | 551 |
| 530 // The number of integer digits may differ from the number of digits stored | 552 // The number of integer digits may differ from the number of digits stored |
| 531 // in the decimal number. | 553 // in the decimal number. |
| 532 // for 12.345 numIntDigits = 2, number->digits = 5 | 554 // for 12.345 numIntDigits = 2, number->digits = 5 |
| 533 // for 12E4 numIntDigits = 6, number->digits = 2 | 555 // for 12E4 numIntDigits = 6, number->digits = 2 |
| 534 // The conversion ignores the fraction digits in the first case, | 556 // The conversion ignores the fraction digits in the first case, |
| 535 // and fakes up extra zero digits in the second. | 557 // and fakes up extra zero digits in the second. |
| 536 // TODO: It would be faster to store a table of powers of ten to multiply b
y | 558 // TODO: It would be faster to store a table of powers of ten to multiply b
y |
| 537 // instead of looping over zero digits, multiplying each time. | 559 // instead of looping over zero digits, multiplying each time. |
| 538 | 560 |
| 539 int32_t numIntDigits = fDecNumber->digits + fDecNumber->exponent; | 561 int32_t numIntDigits = getUpperExponent(); |
| 540 uint64_t value = 0; | 562 uint64_t value = 0; |
| 541 for (int32_t i = 0; i < numIntDigits; i++) { | 563 for (int32_t i = 0; i < numIntDigits; i++) { |
| 542 // Loop is iterating over digits starting with the most significant. | 564 // Loop is iterating over digits starting with the most significant. |
| 543 // Numbers are stored with the least significant digit at index zero. | 565 // Numbers are stored with the least significant digit at index zero. |
| 544 int32_t digitIndex = fDecNumber->digits - i - 1; | 566 int32_t digitIndex = fDecNumber->digits - i - 1; |
| 545 int32_t v = (digitIndex >= 0) ? fDecNumber->lsu[digitIndex] : 0; | 567 int32_t v = (digitIndex >= 0) ? fDecNumber->lsu[digitIndex] : 0; |
| 546 value = value * (uint64_t)10 + (uint64_t)v; | 568 value = value * (uint64_t)10 + (uint64_t)v; |
| 547 } | 569 } |
| 548 | 570 |
| 549 if (decNumberIsNegative(fDecNumber)) { | 571 if (decNumberIsNegative(fDecNumber)) { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 604 uprv_decNumberTrim(this->fDecNumber); | 626 uprv_decNumberTrim(this->fDecNumber); |
| 605 if (fDecNumber->exponent < 0) { | 627 if (fDecNumber->exponent < 0) { |
| 606 // Number contains fraction digits. | 628 // Number contains fraction digits. |
| 607 return FALSE; | 629 return FALSE; |
| 608 } | 630 } |
| 609 if (decNumberIsZero(this->fDecNumber) && !ignoreNegativeZero && | 631 if (decNumberIsZero(this->fDecNumber) && !ignoreNegativeZero && |
| 610 (fDecNumber->bits & DECNEG) != 0) { | 632 (fDecNumber->bits & DECNEG) != 0) { |
| 611 // Negative Zero, not ingored. Cannot represent as a long. | 633 // Negative Zero, not ingored. Cannot represent as a long. |
| 612 return FALSE; | 634 return FALSE; |
| 613 } | 635 } |
| 614 if (fDecNumber->digits + fDecNumber->exponent < 10) { | 636 if (getUpperExponent() < 10) { |
| 615 // The number is 9 or fewer digits. | 637 // The number is 9 or fewer digits. |
| 616 // The max and min int32 are 10 digts, so this number fits. | 638 // The max and min int32 are 10 digts, so this number fits. |
| 617 // This is the common case. | 639 // This is the common case. |
| 618 return TRUE; | 640 return TRUE; |
| 619 } | 641 } |
| 620 | 642 |
| 621 // TODO: Should cache these constants; construction is relatively costly. | 643 // TODO: Should cache these constants; construction is relatively costly. |
| 622 // But not of huge consequence; they're only needed for 10 digit ints
. | 644 // But not of huge consequence; they're only needed for 10 digit ints
. |
| 623 UErrorCode status = U_ZERO_ERROR; | 645 UErrorCode status = U_ZERO_ERROR; |
| 624 DigitList min32; min32.set("-2147483648", status); | 646 DigitList min32; min32.set("-2147483648", status); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 651 uprv_decNumberTrim(this->fDecNumber); | 673 uprv_decNumberTrim(this->fDecNumber); |
| 652 if (fDecNumber->exponent < 0) { | 674 if (fDecNumber->exponent < 0) { |
| 653 // Number contains fraction digits. | 675 // Number contains fraction digits. |
| 654 return FALSE; | 676 return FALSE; |
| 655 } | 677 } |
| 656 if (decNumberIsZero(this->fDecNumber) && !ignoreNegativeZero && | 678 if (decNumberIsZero(this->fDecNumber) && !ignoreNegativeZero && |
| 657 (fDecNumber->bits & DECNEG) != 0) { | 679 (fDecNumber->bits & DECNEG) != 0) { |
| 658 // Negative Zero, not ingored. Cannot represent as a long. | 680 // Negative Zero, not ingored. Cannot represent as a long. |
| 659 return FALSE; | 681 return FALSE; |
| 660 } | 682 } |
| 661 if (fDecNumber->digits + fDecNumber->exponent < 19) { | 683 if (getUpperExponent() < 19) { |
| 662 // The number is 18 or fewer digits. | 684 // The number is 18 or fewer digits. |
| 663 // The max and min int64 are 19 digts, so this number fits. | 685 // The max and min int64 are 19 digts, so this number fits. |
| 664 // This is the common case. | 686 // This is the common case. |
| 665 return TRUE; | 687 return TRUE; |
| 666 } | 688 } |
| 667 | 689 |
| 668 // TODO: Should cache these constants; construction is relatively costly. | 690 // TODO: Should cache these constants; construction is relatively costly. |
| 669 // But not of huge consequence; they're only needed for 19 digit ints
. | 691 // But not of huge consequence; they're only needed for 19 digit ints
. |
| 670 UErrorCode status = U_ZERO_ERROR; | 692 UErrorCode status = U_ZERO_ERROR; |
| 671 DigitList min64; min64.set("-9223372036854775808", status); | 693 DigitList min64; min64.set("-9223372036854775808", status); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 825 // ------------------------------------- | 847 // ------------------------------------- |
| 826 | 848 |
| 827 /* | 849 /* |
| 828 * Multiply | 850 * Multiply |
| 829 * The number will be expanded if need be to retain full precision. | 851 * The number will be expanded if need be to retain full precision. |
| 830 * In practice, for formatting, multiply is by 10, 100 or 1000, so more dig
its | 852 * In practice, for formatting, multiply is by 10, 100 or 1000, so more dig
its |
| 831 * will not be required for this use. | 853 * will not be required for this use. |
| 832 */ | 854 */ |
| 833 void | 855 void |
| 834 DigitList::mult(const DigitList &other, UErrorCode &status) { | 856 DigitList::mult(const DigitList &other, UErrorCode &status) { |
| 857 if (U_FAILURE(status)) { |
| 858 return; |
| 859 } |
| 835 fContext.status = 0; | 860 fContext.status = 0; |
| 836 int32_t requiredDigits = this->digits() + other.digits(); | 861 int32_t requiredDigits = this->digits() + other.digits(); |
| 837 if (requiredDigits > fContext.digits) { | 862 if (requiredDigits > fContext.digits) { |
| 838 reduce(); // Remove any trailing zeros | 863 reduce(); // Remove any trailing zeros |
| 839 int32_t requiredDigits = this->digits() + other.digits(); | 864 int32_t requiredDigits = this->digits() + other.digits(); |
| 840 ensureCapacity(requiredDigits, status); | 865 ensureCapacity(requiredDigits, status); |
| 841 } | 866 } |
| 842 uprv_decNumberMultiply(fDecNumber, fDecNumber, other.fDecNumber, &fContext); | 867 uprv_decNumberMultiply(fDecNumber, fDecNumber, other.fDecNumber, &fContext); |
| 843 internalClear(); | 868 internalClear(); |
| 844 } | 869 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 895 // ------------------------------------- | 920 // ------------------------------------- |
| 896 | 921 |
| 897 /** | 922 /** |
| 898 * Round the representation to the given number of digits. | 923 * Round the representation to the given number of digits. |
| 899 * @param maximumDigits The maximum number of digits to be shown. | 924 * @param maximumDigits The maximum number of digits to be shown. |
| 900 * Upon return, count will be less than or equal to maximumDigits. | 925 * Upon return, count will be less than or equal to maximumDigits. |
| 901 */ | 926 */ |
| 902 void | 927 void |
| 903 DigitList::round(int32_t maximumDigits) | 928 DigitList::round(int32_t maximumDigits) |
| 904 { | 929 { |
| 930 reduce(); |
| 931 if (maximumDigits >= fDecNumber->digits) { |
| 932 return; |
| 933 } |
| 905 int32_t savedDigits = fContext.digits; | 934 int32_t savedDigits = fContext.digits; |
| 906 fContext.digits = maximumDigits; | 935 fContext.digits = maximumDigits; |
| 907 uprv_decNumberPlus(fDecNumber, fDecNumber, &fContext); | 936 uprv_decNumberPlus(fDecNumber, fDecNumber, &fContext); |
| 908 fContext.digits = savedDigits; | 937 fContext.digits = savedDigits; |
| 909 uprv_decNumberTrim(fDecNumber); | 938 uprv_decNumberTrim(fDecNumber); |
| 939 reduce(); |
| 910 internalClear(); | 940 internalClear(); |
| 911 } | 941 } |
| 912 | 942 |
| 913 | 943 |
| 914 void | 944 void |
| 915 DigitList::roundFixedPoint(int32_t maximumFractionDigits) { | 945 DigitList::roundFixedPoint(int32_t maximumFractionDigits) { |
| 916 trim(); // Remove trailing zeros. | 946 reduce(); // Remove trailing zeros. |
| 917 if (fDecNumber->exponent >= -maximumFractionDigits) { | 947 if (fDecNumber->exponent >= -maximumFractionDigits) { |
| 918 return; | 948 return; |
| 919 } | 949 } |
| 920 decNumber scale; // Dummy decimal number, but with the desired number of | 950 decNumber scale; // Dummy decimal number, but with the desired number of |
| 921 uprv_decNumberZero(&scale); // fraction digits. | 951 uprv_decNumberZero(&scale); // fraction digits. |
| 922 scale.exponent = -maximumFractionDigits; | 952 scale.exponent = -maximumFractionDigits; |
| 923 scale.lsu[0] = 1; | 953 scale.lsu[0] = 1; |
| 924 | 954 |
| 925 uprv_decNumberQuantize(fDecNumber, fDecNumber, &scale, &fContext); | 955 uprv_decNumberQuantize(fDecNumber, fDecNumber, &scale, &fContext); |
| 926 trim(); | 956 reduce(); |
| 927 internalClear(); | 957 internalClear(); |
| 928 } | 958 } |
| 929 | 959 |
| 930 // ------------------------------------- | 960 // ------------------------------------- |
| 931 | 961 |
| 932 void | 962 void |
| 933 DigitList::toIntegralValue() { | 963 DigitList::toIntegralValue() { |
| 934 uprv_decNumberToIntegralValue(fDecNumber, fDecNumber, &fContext); | 964 uprv_decNumberToIntegralValue(fDecNumber, fDecNumber, &fContext); |
| 935 } | 965 } |
| 936 | 966 |
| 937 | 967 |
| 938 // ------------------------------------- | 968 // ------------------------------------- |
| 939 UBool | 969 UBool |
| 940 DigitList::isZero() const | 970 DigitList::isZero() const |
| 941 { | 971 { |
| 942 return decNumberIsZero(fDecNumber); | 972 return decNumberIsZero(fDecNumber); |
| 943 } | 973 } |
| 944 | 974 |
| 975 // ------------------------------------- |
| 976 int32_t |
| 977 DigitList::getUpperExponent() const { |
| 978 return fDecNumber->digits + fDecNumber->exponent; |
| 979 } |
| 980 |
| 981 DigitInterval & |
| 982 DigitList::getSmallestInterval(DigitInterval &result) const { |
| 983 result.setLeastSignificantInclusive(fDecNumber->exponent); |
| 984 result.setMostSignificantExclusive(getUpperExponent()); |
| 985 return result; |
| 986 } |
| 987 |
| 988 uint8_t |
| 989 DigitList::getDigitByExponent(int32_t exponent) const { |
| 990 int32_t idx = exponent - fDecNumber->exponent; |
| 991 if (idx < 0 || idx >= fDecNumber->digits) { |
| 992 return 0; |
| 993 } |
| 994 return fDecNumber->lsu[idx]; |
| 995 } |
| 996 |
| 997 void |
| 998 DigitList::appendDigitsTo(CharString &str, UErrorCode &status) const { |
| 999 str.append((const char *) fDecNumber->lsu, fDecNumber->digits, status); |
| 1000 } |
| 1001 |
| 1002 void |
| 1003 DigitList::roundAtExponent(int32_t exponent, int32_t maxSigDigits) { |
| 1004 reduce(); |
| 1005 if (maxSigDigits < fDecNumber->digits) { |
| 1006 int32_t minExponent = getUpperExponent() - maxSigDigits; |
| 1007 if (exponent < minExponent) { |
| 1008 exponent = minExponent; |
| 1009 } |
| 1010 } |
| 1011 if (exponent <= fDecNumber->exponent) { |
| 1012 return; |
| 1013 } |
| 1014 int32_t digits = getUpperExponent() - exponent; |
| 1015 if (digits > 0) { |
| 1016 round(digits); |
| 1017 } else { |
| 1018 roundFixedPoint(-exponent); |
| 1019 } |
| 1020 } |
| 1021 |
| 1022 void |
| 1023 DigitList::quantize(const DigitList &quantity, UErrorCode &status) { |
| 1024 if (U_FAILURE(status)) { |
| 1025 return; |
| 1026 } |
| 1027 div(quantity, status); |
| 1028 roundAtExponent(0); |
| 1029 mult(quantity, status); |
| 1030 reduce(); |
| 1031 } |
| 1032 |
| 1033 int32_t |
| 1034 DigitList::getScientificExponent( |
| 1035 int32_t minIntDigitCount, int32_t exponentMultiplier) const { |
| 1036 // The exponent for zero is always zero. |
| 1037 if (isZero()) { |
| 1038 return 0; |
| 1039 } |
| 1040 int32_t intDigitCount = getUpperExponent(); |
| 1041 int32_t exponent; |
| 1042 if (intDigitCount >= minIntDigitCount) { |
| 1043 int32_t maxAdjustment = intDigitCount - minIntDigitCount; |
| 1044 exponent = (maxAdjustment / exponentMultiplier) * exponentMultiplier; |
| 1045 } else { |
| 1046 int32_t minAdjustment = minIntDigitCount - intDigitCount; |
| 1047 exponent = ((minAdjustment + exponentMultiplier - 1) / exponentMultiplie
r) * -exponentMultiplier; |
| 1048 } |
| 1049 return exponent; |
| 1050 } |
| 1051 |
| 1052 int32_t |
| 1053 DigitList::toScientific( |
| 1054 int32_t minIntDigitCount, int32_t exponentMultiplier) { |
| 1055 int32_t exponent = getScientificExponent( |
| 1056 minIntDigitCount, exponentMultiplier); |
| 1057 shiftDecimalRight(-exponent); |
| 1058 return exponent; |
| 1059 } |
| 1060 |
| 1061 void |
| 1062 DigitList::shiftDecimalRight(int32_t n) { |
| 1063 fDecNumber->exponent += n; |
| 1064 internalClear(); |
| 1065 } |
| 1066 |
| 945 U_NAMESPACE_END | 1067 U_NAMESPACE_END |
| 946 #endif // #if !UCONFIG_NO_FORMATTING | 1068 #endif // #if !UCONFIG_NO_FORMATTING |
| 947 | 1069 |
| 948 //eof | 1070 //eof |
| OLD | NEW |