/*
**********************************************************************
-* Copyright (C) 1997-2012, International Business Machines
+* Copyright (C) 1997-2015, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
*
/* 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
fDecNumber = fStorage.getAlias();
uprv_decNumberZero(fDecNumber);
- fDouble = 0.0;
- fHaveDouble = TRUE;
+ internalSetDouble(0.0);
}
// -------------------------------------
// 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;
{
uprv_decNumberZero(fDecNumber);
uprv_decContextSetRounding(&fContext, DEC_ROUND_HALF_EVEN);
- fDouble = 0.0;
- fHaveDouble = TRUE;
+ internalSetDouble(0.0);
}
} else {
fDecNumber->bits |= DECNEG;
}
- fHaveDouble = FALSE;
+ internalClear();
}
// -------------------------------------
adjustedDigits = 0;
}
fDecNumber->exponent = d - adjustedDigits;
- fHaveDouble = FALSE;
+ internalClear();
}
int32_t
fDecNumber->lsu[0] = 0;
}
fDecNumber->digits = c;
- fHaveDouble = FALSE;
+ internalClear();
}
int32_t
U_ASSERT(v>='0' && v<='9');
v &= 0x0f;
fDecNumber->lsu[count-i-1] = v;
- fHaveDouble = FALSE;
+ internalClear();
}
char
fDecNumber->exponent--;
}
}
- fHaveDouble = FALSE;
+ internalClear();
}
// -------------------------------------
char decimalSeparator;
{
Mutex mutex;
- if (fHaveDouble) {
- return fDouble;
+ if (fHave == kDouble) {
+ return fUnion.fDouble;
+ } else if(fHave == kInt64) {
+ return (double)fUnion.fInt64;
}
decimalSeparator = gDecimal;
}
tDouble = std::numeric_limits<double>::max();
}
if (!isPositive()) {
- tDouble = -fDouble;
+ tDouble = -tDouble; //this was incorrectly "-fDouble" originally.
}
} else {
MaybeStackArray<char, MAX_DBL_DIGITS+18> s;
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<DigitList *>(this);
- nonConstThis->fDouble = tDouble;
- nonConstThis->fHaveDouble = TRUE;
+ nonConstThis->internalSetDouble(tDouble);
gDecimal = decimalSeparator;
}
return tDouble;
* 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)
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)
U_ASSERT(uprv_strlen(str) < sizeof(str));
uprv_decNumberFromString(fDecNumber, str, &fContext);
- fDouble = (double)source;
- fHaveDouble = TRUE;
+ internalSetDouble(static_cast<double>(source));
+}
+
+/**
+ * Set an int64, with no decnumber
+ */
+void
+DigitList::setInteger(int64_t source)
+{
+ fDecNumber=NULL;
+ internalSetInt64(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();
}
/**
// Create a decNumber from the string.
uprv_decNumberFromString(fDecNumber, rep, &fContext);
uprv_decNumberTrim(fDecNumber);
- fDouble = source;
- fHaveDouble = TRUE;
+ internalSetDouble(source);
}
// -------------------------------------
ensureCapacity(requiredDigits, status);
}
uprv_decNumberMultiply(fDecNumber, fDecNumber, other.fDecNumber, &fContext);
- fHaveDouble = FALSE;
+ internalClear();
}
// -------------------------------------
return;
}
uprv_decNumberDivide(fDecNumber, fDecNumber, other.fDecNumber, &fContext);
- fHaveDouble = FALSE;
+ internalClear();
}
// -------------------------------------
uprv_decNumberPlus(fDecNumber, fDecNumber, &fContext);
fContext.digits = savedDigits;
uprv_decNumberTrim(fDecNumber);
- fHaveDouble = FALSE;
+ internalClear();
}
uprv_decNumberQuantize(fDecNumber, fDecNumber, &scale, &fContext);
trim();
- fHaveDouble = FALSE;
+ internalClear();
}
// -------------------------------------
return decNumberIsZero(fDecNumber);
}
-
U_NAMESPACE_END
#endif // #if !UCONFIG_NO_FORMATTING