Пример #1
0
// -------------------------------------
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;
}   
Пример #2
0
/**
 * 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;
}
Пример #4
0
/**
 * 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));
}
Пример #5
0
/**
 * 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();
}
Пример #6
0
// -------------------------------------
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;
}
Пример #7
0
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;
}