// ------------------------------------- void DigitList::set(const StringPiece &source, UErrorCode &status) { 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) { fContext.digits = numDigits; char *t = fStorage.resize(sizeof(decNumber) + numDigits, fStorage.getCapacity()); if (t == NULL) { status = U_MEMORY_ALLOCATION_ERROR; return; } fDecNumber = (decNumber *)fStorage.getAlias(); } fContext.status = 0; uprv_decNumberFromString(fDecNumber, source.data(), &fContext); if ((fContext.status & DEC_Conversion_syntax) != 0) { status = U_DECIMAL_NUMBER_SYNTAX_ERROR; } fHaveDouble = FALSE; }
/** * Set the digit list to a representation of the given double value. * This method supports both fixed-point and exponential notation. * @param source Value to be converted. */ void DigitList::set(double source) { // for now, simple implementation; later, do proper IEEE stuff char rep[MAX_DIGITS + 8]; // Extra space for '+', '.', e+NNN, and '\0' (actually +8 is enough) // Generate a representation of the form /[+-][0-9].[0-9]+e[+-][0-9]+/ // Can also generate /[+-]nan/ or /[+-]inf/ // TODO: Use something other than sprintf() here, since it's behavior is somewhat platform specific. // That is why infinity is special cased here. if (uprv_isInfinite(source)) { if (uprv_isNegativeInfinity(source)) { uprv_strcpy(rep,"-inf"); // Handle negative infinity } else { uprv_strcpy(rep,"inf"); } } else { sprintf(rep, "%+1.*e", MAX_DBL_DIGITS - 1, source); } U_ASSERT(uprv_strlen(rep) < sizeof(rep)); // uprv_decNumberFromString() will parse the string expecting '.' as a // decimal separator, however sprintf() can use ',' in certain locales. // Overwrite a ',' with '.' here before proceeding. char *decimalSeparator = strchr(rep, ','); if (decimalSeparator != NULL) { *decimalSeparator = '.'; } // Create a decNumber from the string. uprv_decNumberFromString(fDecNumber, rep, &fContext); uprv_decNumberTrim(fDecNumber); internalSetDouble(source); }
/** * Set the digit list to a representation of the given double value. * This method supports both fixed-point and exponential notation. * @param source Value to be converted. */ void DigitList::set(double source) { // for now, simple implementation; later, do proper IEEE stuff char rep[MAX_DIGITS + 8]; // Extra space for '+', '.', e+NNN, and '\0' (actually +8 is enough) // Generate a representation of the form /[+-][0-9]+e[+-][0-9]+/ sprintf(rep, "%+1.*e", MAX_DBL_DIGITS - 1, source); U_ASSERT(uprv_strlen(rep) < sizeof(rep)); // uprv_decNumberFromString() will parse the string expecting '.' as a // decimal separator, however sprintf() can use ',' in certain locales. // Overwrite a different decimal separator with '.' here before proceeding. loadDecimalChar(); if (gDecimal != '.') { char *decimalPt = strchr(rep, gDecimal); if (decimalPt != NULL) { *decimalPt = '.'; } } // Create a decNumber from the string. uprv_decNumberFromString(fDecNumber, rep, &fContext); uprv_decNumberTrim(fDecNumber); fDouble = source; fHaveDouble = TRUE; }
/** * Set an int64, via decnumber */ void DigitList::set(int64_t source) { char str[MAX_DIGITS+2]; // Leave room for sign and trailing nul. formatBase10(source, str); U_ASSERT(uprv_strlen(str) < sizeof(str)); uprv_decNumberFromString(fDecNumber, str, &fContext); internalSetDouble(static_cast<double>(source)); }
/** * Set the DigitList from a decimal number string. * * The incoming string _must_ be nul terminated, even though it is arriving * as a StringPiece because that is what the decNumber library wants. * We can get away with this for an internal function; it would not * be acceptable for a public API. */ void DigitList::set(StringPiece source, UErrorCode &status, uint32_t /*fastpathBits*/) { if (U_FAILURE(status)) { return; } #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; } fDecNumber = t; fContext.digits = numDigits; } fContext.status = 0; uprv_decNumberFromString(fDecNumber, source.data(), &fContext); if ((fContext.status & DEC_Conversion_syntax) != 0) { status = U_DECIMAL_NUMBER_SYNTAX_ERROR; } } internalClear(); }
// ------------------------------------- void DigitList::set(int64_t source) { char str[MAX_DIGITS+2]; // Leave room for sign and trailing nul. formatBase10(source, str); U_ASSERT(uprv_strlen(str) < sizeof(str)); uprv_decNumberFromString(fDecNumber, str, &fContext); fDouble = (double)source; fHaveDouble = TRUE; }
void DigitList::set(double source) { // for now, simple implementation; later, do proper IEEE stuff char rep[MAX_DIGITS + 8]; // Extra space for '+', '.', e+NNN, and '\0' (actually +8 is enough) // Generate a representation of the form /[+-][0-9]+e[+-][0-9]+/ sprintf(rep, "%+1.*e", MAX_DBL_DIGITS - 1, source); U_ASSERT(uprv_strlen(rep) < sizeof(rep)); // Create a decNumber from the string. uprv_decNumberFromString(fDecNumber, rep, &fContext); uprv_decNumberTrim(fDecNumber); fDouble = source; fHaveDouble = TRUE; }