/**
 * 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;
}
Beispiel #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);
}
Beispiel #3
0
void
DigitList::round(int32_t maximumDigits)
{
    int32_t savedDigits  = fContext.digits;
    fContext.digits = maximumDigits;
    uprv_decNumberPlus(fDecNumber, fDecNumber, &fContext);
    fContext.digits = savedDigits;
    uprv_decNumberTrim(fDecNumber);
    fHaveDouble = FALSE;
}
/**
 * Round the representation to the given number of digits.
 * @param maximumDigits The maximum number of digits to be shown.
 * Upon return, count will be less than or equal to maximumDigits.
 */
void
DigitList::round(int32_t maximumDigits)
{
    int32_t savedDigits  = fContext.digits;
    fContext.digits = maximumDigits;
    uprv_decNumberPlus(fDecNumber, fDecNumber, &fContext);
    fContext.digits = savedDigits;
    uprv_decNumberTrim(fDecNumber);
    internalClear();
}
Beispiel #5
0
/**
 * Round the representation to the given number of digits.
 * @param maximumDigits The maximum number of digits to be shown.
 * Upon return, count will be less than or equal to maximumDigits.
 */
void
DigitList::round(int32_t maximumDigits)
{
    reduce();
    if (maximumDigits >= fDecNumber->digits) {
        return;
    }
    int32_t savedDigits  = fContext.digits;
    fContext.digits = maximumDigits;
    uprv_decNumberPlus(fDecNumber, fDecNumber, &fContext);
    fContext.digits = savedDigits;
    uprv_decNumberTrim(fDecNumber);
    reduce();
    internalClear();
}
Beispiel #6
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;
}
Beispiel #7
0
/**
 * Return true if the number represented by this object can fit into
 * a long.
 */
UBool
DigitList::fitsIntoInt64(UBool ignoreNegativeZero) /*const*/
{
    if (decNumberIsSpecial(this->fDecNumber)) {
        // NaN or Infinity.  Does not fit in int32.
        return FALSE;
    }
    uprv_decNumberTrim(this->fDecNumber);
    if (fDecNumber->exponent < 0) {
        // Number contains fraction digits.
        return FALSE;
    }
    if (decNumberIsZero(this->fDecNumber) && !ignoreNegativeZero &&
        (fDecNumber->bits & DECNEG) != 0) {
        // Negative Zero, not ingored.  Cannot represent as a long.
        return FALSE;
    }
    if (getUpperExponent() < 19) {
        // The number is 18 or fewer digits.
        // The max and min int64 are 19 digts, so this number fits.
        // This is the common case.
        return TRUE;
    }

    // TODO:  Should cache these constants; construction is relatively costly.
    //        But not of huge consequence; they're only needed for 19 digit ints.
    UErrorCode status = U_ZERO_ERROR;
    DigitList min64; min64.set("-9223372036854775808", status);
    if (this->compare(min64) < 0) {
        return FALSE;
    }
    DigitList max64; max64.set("9223372036854775807", status);
    if (this->compare(max64) > 0) {
        return FALSE;
    }
    if (U_FAILURE(status)) {
        return FALSE;
    }
    return true;
}
Beispiel #8
0
// -------------------------------------
//  trim - remove trailing fraction zero digits.
void
DigitList::trim() {
    uprv_decNumberTrim(fDecNumber);
}