/** * 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 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); }
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(); }
/** * 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(); }
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; }
/** * 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; }
// ------------------------------------- // trim - remove trailing fraction zero digits. void DigitList::trim() { uprv_decNumberTrim(fDecNumber); }