// Allow implicit conversion from char16_t* to UnicodeString for this file: // Helpful in toString methods and elsewhere. #define UNISTR_FROM_STRING_EXPLICIT
// Attempt to get the pattern with the native numbering system.
UErrorCode localStatus = U_ZERO_ERROR; const char16_t* pattern;
pattern = doGetPattern(res.getAlias(), nsName, patternKey, status, localStatus); if (U_FAILURE(status)) { return u""; }
// Fall back to latn if native numbering system does not have the right pattern if (U_FAILURE(localStatus) && uprv_strcmp("latn", nsName) != 0) {
localStatus = U_ZERO_ERROR;
pattern = doGetPattern(res.getAlias(), "latn", patternKey, status, localStatus); if (U_FAILURE(status)) { return u""; }
}
return pattern;
}
DecNum::DecNum() {
uprv_decContextDefault(&fContext, DEC_INIT_BASE);
uprv_decContextSetRounding(&fContext, DEC_ROUND_HALF_EVEN);
fContext.traps = 0; // no traps, thank you (what does this even mean?)
}
DecNum::DecNum(const DecNum& other, UErrorCode& status)
: fContext(other.fContext) { // Allocate memory for the new DecNum.
U_ASSERT(fContext.digits == other.fData.getCapacity()); if (fContext.digits > kDefaultDigits) { void* p = fData.resize(fContext.digits, 0); if (p == nullptr) {
status = U_MEMORY_ALLOCATION_ERROR; return;
}
}
// Copy the data from the old DecNum to the new one.
uprv_memcpy(fData.getAlias(), other.fData.getAlias(), sizeof(decNumber));
uprv_memcpy(fData.getArrayStart(),
other.fData.getArrayStart(),
other.fData.getArrayLimit() - other.fData.getArrayStart());
}
void DecNum::setTo(StringPiece str, UErrorCode& status) { // We need NUL-terminated for decNumber; CharString guarantees this, but not StringPiece.
CharString cstr(str, status); if (U_FAILURE(status)) { return; }
_setTo(cstr.data(), str.length(), status);
}
void DecNum::setTo(double d, UErrorCode& status) { // Need to check for NaN and Infinity before going into DoubleToStringConverter if (std::isnan(d) != 0 || std::isfinite(d) == 0) {
status = U_UNSUPPORTED_ERROR; return;
}
// First convert from double to string, then string to DecNum. // Allocate enough room for: all digits, "E-324", and NUL-terminator. char buffer[DoubleToStringConverter::kBase10MaximalLength + 6]; bool sign; // unused; always positive
int32_t length;
int32_t point;
DoubleToStringConverter::DoubleToAscii(
d,
DoubleToStringConverter::DtoaMode::SHORTEST,
0,
buffer, sizeof(buffer),
&sign,
&length,
&point
);
// Read initial result as a string.
_setTo(buffer, length, status);
// Set exponent and bitmask. Note that DoubleToStringConverter does not do negatives.
fData.getAlias()->exponent += point - length;
fData.getAlias()->bits |= static_cast<uint8_t>(std::signbit(d) ? DECNEG : 0);
}
static_assert(DECDPUN == 1, "Assumes that DECDPUN is set to 1");
uprv_decNumberFromString(fData.getAlias(), str, &fContext);
// Check for invalid syntax and set the corresponding error code. if ((fContext.status & DEC_Conversion_syntax) != 0) {
status = U_DECIMAL_NUMBER_SYNTAX_ERROR; return;
} elseif (fContext.status != 0) { // Not a syntax error, but some other error, like an exponent that is too large.
status = U_UNSUPPORTED_ERROR; return;
}
}
// "digits is of type int32_t, and must have a value in the range 1 through 999,999,999." if (length < 1 || length > 999999999) { // Too large for decNumber
status = U_UNSUPPORTED_ERROR; return;
} // "The exponent field holds the exponent of the number. Its range is limited by the requirement that // "the range of the adjusted exponent of the number be balanced and fit within a whole number of // "decimal digits (in this implementation, be –999,999,999 through +999,999,999). The adjusted // "exponent is the exponent that would result if the number were expressed with a single digit before // "the decimal point, and is therefore given by exponent+digits-1." if (scale > 999999999 - length + 1 || scale < -999999999 - length + 1) { // Too large for decNumber
status = U_UNSUPPORTED_ERROR; return;
}
fData.getAlias()->digits = length;
fData.getAlias()->exponent = scale;
fData.getAlias()->bits = static_cast<uint8_t>(isNegative ? DECNEG : 0);
uprv_decNumberSetBCD(fData, bcd, static_cast<uint32_t>(length)); if (fContext.status != 0) { // Some error occurred while constructing the decNumber.
status = U_INTERNAL_PROGRAM_ERROR;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.