X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/4388f060552cc537e71e957d32f35e9d75a61233..b331163bffd790ced0e88b73f44f86d49ccc48a5:/icuSources/i18n/digitlst.cpp diff --git a/icuSources/i18n/digitlst.cpp b/icuSources/i18n/digitlst.cpp index b885a17c..51738bec 100644 --- a/icuSources/i18n/digitlst.cpp +++ b/icuSources/i18n/digitlst.cpp @@ -1,6 +1,6 @@ /* ********************************************************************** -* Copyright (C) 1997-2012, International Business Machines +* Copyright (C) 1997-2015, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * @@ -54,8 +54,8 @@ /* Only for 32 bit numbers. Ignore the negative sign. */ -static const char LONG_MIN_REP[] = "2147483648"; -static const char I64_MIN_REP[] = "9223372036854775808"; +//static const char LONG_MIN_REP[] = "2147483648"; +//static const char I64_MIN_REP[] = "9223372036854775808"; U_NAMESPACE_BEGIN @@ -73,8 +73,7 @@ DigitList::DigitList() fDecNumber = fStorage.getAlias(); uprv_decNumberZero(fDecNumber); - fDouble = 0.0; - fHaveDouble = TRUE; + internalSetDouble(0.0); } // ------------------------------------- @@ -116,8 +115,13 @@ DigitList::operator=(const DigitList& other) // Avoid potential races with that happening with other.fDouble // while we are doing the assignment. Mutex mutex; - fDouble = other.fDouble; - fHaveDouble = other.fHaveDouble; + + if(other.fHave==kDouble) { + fUnion.fDouble = other.fUnion.fDouble; + } else if(other.fHave==kInt64) { + fUnion.fInt64 = other.fUnion.fInt64; + } + fHave = other.fHave; } } return *this; @@ -190,8 +194,7 @@ DigitList::clear() { uprv_decNumberZero(fDecNumber); uprv_decContextSetRounding(&fContext, DEC_ROUND_HALF_EVEN); - fDouble = 0.0; - fHaveDouble = TRUE; + internalSetDouble(0.0); } @@ -278,7 +281,7 @@ DigitList::setPositive(UBool s) { } else { fDecNumber->bits |= DECNEG; } - fHaveDouble = FALSE; + internalClear(); } // ------------------------------------- @@ -293,7 +296,7 @@ DigitList::setDecimalAt(int32_t d) { adjustedDigits = 0; } fDecNumber->exponent = d - adjustedDigits; - fHaveDouble = FALSE; + internalClear(); } int32_t @@ -315,7 +318,7 @@ DigitList::setCount(int32_t c) { fDecNumber->lsu[0] = 0; } fDecNumber->digits = c; - fHaveDouble = FALSE; + internalClear(); } int32_t @@ -336,7 +339,7 @@ DigitList::setDigit(int32_t i, char v) { U_ASSERT(v>='0' && v<='9'); v &= 0x0f; fDecNumber->lsu[count-i-1] = v; - fHaveDouble = FALSE; + internalClear(); } char @@ -390,7 +393,7 @@ DigitList::append(char digit) fDecNumber->exponent--; } } - fHaveDouble = FALSE; + internalClear(); } // ------------------------------------- @@ -409,8 +412,10 @@ DigitList::getDouble() const char decimalSeparator; { Mutex mutex; - if (fHaveDouble) { - return fDouble; + if (fHave == kDouble) { + return fUnion.fDouble; + } else if(fHave == kInt64) { + return (double)fUnion.fInt64; } decimalSeparator = gDecimal; } @@ -438,7 +443,7 @@ DigitList::getDouble() const tDouble = std::numeric_limits::max(); } if (!isPositive()) { - tDouble = -fDouble; + tDouble = -tDouble; //this was incorrectly "-fDouble" originally. } } else { MaybeStackArray s; @@ -453,27 +458,26 @@ DigitList::getDouble() const DigitList numToConvert(*this); numToConvert.reduce(); // Removes any trailing zeros, so that digit count is good. numToConvert.round(MAX_DBL_DIGITS+3); - uprv_decNumberToString(numToConvert.fDecNumber, s); + uprv_decNumberToString(numToConvert.fDecNumber, s.getAlias()); // TODO: how many extra digits should be included for an accurate conversion? } else { - uprv_decNumberToString(this->fDecNumber, s); + uprv_decNumberToString(this->fDecNumber, s.getAlias()); } U_ASSERT(uprv_strlen(&s[0]) < MAX_DBL_DIGITS+18); if (decimalSeparator != '.') { - char *decimalPt = strchr(s, '.'); + char *decimalPt = strchr(s.getAlias(), '.'); if (decimalPt != NULL) { *decimalPt = decimalSeparator; } } char *end = NULL; - tDouble = uprv_strtod(s, &end); + tDouble = uprv_strtod(s.getAlias(), &end); } { Mutex mutex; DigitList *nonConstThis = const_cast(this); - nonConstThis->fDouble = tDouble; - nonConstThis->fHaveDouble = TRUE; + nonConstThis->internalSetDouble(tDouble); gDecimal = decimalSeparator; } return tDouble; @@ -511,6 +515,9 @@ int32_t DigitList::getLong() /*const*/ * Return zero if the number cannot be represented. */ int64_t DigitList::getInt64() /*const*/ { + if(fHave==kInt64) { + return fUnion.fInt64; + } // Truncate if non-integer. // Return 0 if out of range. // Range of in64_t is -9223372036854775808 to 9223372036854775807 (19 digits) @@ -682,14 +689,12 @@ void DigitList::set(int32_t source) { set((int64_t)source); - fDouble = source; - fHaveDouble = TRUE; + internalSetDouble(source); } // ------------------------------------- /** - * @param maximumDigits The maximum digits to be generated. If zero, - * there is no maximum -- generate all digits. + * Set an int64, via decnumber */ void DigitList::set(int64_t source) @@ -699,8 +704,17 @@ DigitList::set(int64_t source) U_ASSERT(uprv_strlen(str) < sizeof(str)); uprv_decNumberFromString(fDecNumber, str, &fContext); - fDouble = (double)source; - fHaveDouble = TRUE; + internalSetDouble(static_cast(source)); +} + +/** + * Set an int64, with no decnumber + */ +void +DigitList::setInteger(int64_t source) +{ + fDecNumber=NULL; + internalSetInt64(source); } @@ -714,31 +728,58 @@ DigitList::set(int64_t source) * be acceptable for a public API. */ void -DigitList::set(const StringPiece &source, UErrorCode &status) { +DigitList::set(const StringPiece &source, UErrorCode &status, uint32_t /*fastpathBits*/) { if (U_FAILURE(status)) { return; } - // Figure out a max number of digits to use during the conversion, and - // resize the number up if necessary. - int32_t numDigits = source.length(); - if (numDigits > fContext.digits) { +#if 0 + if(fastpathBits==(kFastpathOk|kNoDecimal)) { + int32_t size = source.size(); + const char *data = source.data(); + int64_t r = 0; + int64_t m = 1; + // fast parse + while(size>0) { + char ch = data[--size]; + if(ch=='+') { + break; + } else if(ch=='-') { + r = -r; + break; + } else { + int64_t d = ch-'0'; + //printf("CH[%d]=%c, %d, *=%d\n", size,ch, (int)d, (int)m); + r+=(d)*m; + m *= 10; + } + } + //printf("R=%d\n", r); + set(r); + } else +#endif + { + // Figure out a max number of digits to use during the conversion, and + // resize the number up if necessary. + int32_t numDigits = source.length(); + if (numDigits > fContext.digits) { // fContext.digits == fStorage.getCapacity() decNumber *t = fStorage.resize(numDigits, fStorage.getCapacity()); if (t == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; - return; + status = U_MEMORY_ALLOCATION_ERROR; + return; } fDecNumber = t; fContext.digits = numDigits; - } + } - fContext.status = 0; - uprv_decNumberFromString(fDecNumber, source.data(), &fContext); - if ((fContext.status & DEC_Conversion_syntax) != 0) { + fContext.status = 0; + uprv_decNumberFromString(fDecNumber, source.data(), &fContext); + if ((fContext.status & DEC_Conversion_syntax) != 0) { status = U_DECIMAL_NUMBER_SYNTAX_ERROR; + } } - fHaveDouble = FALSE; + internalClear(); } /** @@ -778,8 +819,7 @@ DigitList::set(double source) // Create a decNumber from the string. uprv_decNumberFromString(fDecNumber, rep, &fContext); uprv_decNumberTrim(fDecNumber); - fDouble = source; - fHaveDouble = TRUE; + internalSetDouble(source); } // ------------------------------------- @@ -800,7 +840,7 @@ DigitList::mult(const DigitList &other, UErrorCode &status) { ensureCapacity(requiredDigits, status); } uprv_decNumberMultiply(fDecNumber, fDecNumber, other.fDecNumber, &fContext); - fHaveDouble = FALSE; + internalClear(); } // ------------------------------------- @@ -817,7 +857,7 @@ DigitList::div(const DigitList &other, UErrorCode &status) { return; } uprv_decNumberDivide(fDecNumber, fDecNumber, other.fDecNumber, &fContext); - fHaveDouble = FALSE; + internalClear(); } // ------------------------------------- @@ -867,7 +907,7 @@ DigitList::round(int32_t maximumDigits) uprv_decNumberPlus(fDecNumber, fDecNumber, &fContext); fContext.digits = savedDigits; uprv_decNumberTrim(fDecNumber); - fHaveDouble = FALSE; + internalClear(); } @@ -884,7 +924,7 @@ DigitList::roundFixedPoint(int32_t maximumFractionDigits) { uprv_decNumberQuantize(fDecNumber, fDecNumber, &scale, &fContext); trim(); - fHaveDouble = FALSE; + internalClear(); } // ------------------------------------- @@ -902,7 +942,6 @@ DigitList::isZero() const return decNumberIsZero(fDecNumber); } - U_NAMESPACE_END #endif // #if !UCONFIG_NO_FORMATTING