mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-05 13:35:32 +00:00
parent
f39cf84d62
commit
469456604a
8 changed files with 38 additions and 10 deletions
|
@ -539,7 +539,11 @@ void DecimalQuantity::_setToDecNum(const DecNum& decnum, UErrorCode& status) {
|
|||
if (decnum.isNegative()) {
|
||||
flags |= NEGATIVE_FLAG;
|
||||
}
|
||||
if (!decnum.isZero()) {
|
||||
if (decnum.isNaN()) {
|
||||
flags |= NAN_FLAG;
|
||||
} else if (decnum.isInfinity()) {
|
||||
flags |= INFINITY_FLAG;
|
||||
} else if (!decnum.isZero()) {
|
||||
readDecNumberToBcd(decnum);
|
||||
compact();
|
||||
}
|
||||
|
|
|
@ -56,6 +56,13 @@ class U_I18N_API DecNum : public UMemory {
|
|||
|
||||
bool isZero() const;
|
||||
|
||||
/** Is infinity or NaN */
|
||||
bool isSpecial() const;
|
||||
|
||||
bool isInfinity() const;
|
||||
|
||||
bool isNaN() const;
|
||||
|
||||
void toString(ByteSink& output, UErrorCode& status) const;
|
||||
|
||||
inline CharString toCharString(UErrorCode& status) const {
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "double-conversion.h"
|
||||
#include "number_roundingutils.h"
|
||||
#include "number_skeletons.h"
|
||||
#include "number_decnum.h"
|
||||
#include "putilimp.h"
|
||||
#include "string_segment.h"
|
||||
|
||||
|
@ -35,8 +36,10 @@ void number::impl::parseIncrementOption(const StringSegment &segment,
|
|||
// Utilize DecimalQuantity/decNumber to parse this for us.
|
||||
DecimalQuantity dq;
|
||||
UErrorCode localStatus = U_ZERO_ERROR;
|
||||
dq.setToDecNumber({buffer.data(), buffer.length()}, localStatus);
|
||||
if (U_FAILURE(localStatus)) {
|
||||
DecNum decnum;
|
||||
decnum.setTo({buffer.data(), buffer.length()}, localStatus);
|
||||
dq.setToDecNum(decnum, localStatus);
|
||||
if (U_FAILURE(localStatus) || decnum.isSpecial()) {
|
||||
// throw new SkeletonSyntaxException("Invalid rounding increment", segment, e);
|
||||
status = U_NUMBER_SKELETON_SYNTAX_ERROR;
|
||||
return;
|
||||
|
|
|
@ -1493,7 +1493,7 @@ void blueprint_helpers::parseScaleOption(const StringSegment& segment, MacroProp
|
|||
LocalPointer<DecNum> decnum(new DecNum(), status);
|
||||
if (U_FAILURE(status)) { return; }
|
||||
decnum->setTo({buffer.data(), buffer.length()}, status);
|
||||
if (U_FAILURE(status)) {
|
||||
if (U_FAILURE(status) || decnum->isSpecial()) {
|
||||
// This is a skeleton syntax error; don't let the low-level decnum error bubble up
|
||||
status = U_NUMBER_SKELETON_SYNTAX_ERROR;
|
||||
return;
|
||||
|
|
|
@ -180,12 +180,6 @@ void DecNum::_setTo(const char* str, int32_t maxDigits, UErrorCode& status) {
|
|||
status = U_UNSUPPORTED_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
// For consistency with Java BigDecimal, no support for DecNum that is NaN or Infinity!
|
||||
if (decNumberIsSpecial(fData.getAlias())) {
|
||||
status = U_UNSUPPORTED_ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -252,6 +246,18 @@ bool DecNum::isZero() const {
|
|||
return decNumberIsZero(fData.getAlias());
|
||||
}
|
||||
|
||||
bool DecNum::isSpecial() const {
|
||||
return decNumberIsSpecial(fData.getAlias());
|
||||
}
|
||||
|
||||
bool DecNum::isInfinity() const {
|
||||
return decNumberIsInfinite(fData.getAlias());
|
||||
}
|
||||
|
||||
bool DecNum::isNaN() const {
|
||||
return decNumberIsNaN(fData.getAlias());
|
||||
}
|
||||
|
||||
void DecNum::toString(ByteSink& output, UErrorCode& status) const {
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
|
|
|
@ -677,6 +677,8 @@ void NumberRangeFormatterTest::testNaNInfinity() {
|
|||
auto result4 = lnf.formatFormattableRange(uprv_getNaN(), 0, status);
|
||||
auto result5 = lnf.formatFormattableRange(0, uprv_getNaN(), status);
|
||||
auto result6 = lnf.formatFormattableRange(uprv_getNaN(), uprv_getNaN(), status);
|
||||
auto result7 = lnf.formatFormattableRange({"1000", status}, {"Infinity", status}, status);
|
||||
auto result8 = lnf.formatFormattableRange({"-Infinity", status}, {"NaN", status}, status);
|
||||
|
||||
assertEquals("0 - inf", u"-∞ – 0", result1.toTempString(status));
|
||||
assertEquals("-inf - 0", u"0–∞", result2.toTempString(status));
|
||||
|
@ -684,6 +686,8 @@ void NumberRangeFormatterTest::testNaNInfinity() {
|
|||
assertEquals("NaN - 0", u"NaN–0", result4.toTempString(status));
|
||||
assertEquals("0 - NaN", u"0–NaN", result5.toTempString(status));
|
||||
assertEquals("NaN - NaN", u"~NaN", result6.toTempString(status));
|
||||
assertEquals("1000 - inf", u"1,000–∞", result7.toTempString(status));
|
||||
assertEquals("-inf - NaN", u"-∞ – NaN", result8.toTempString(status));
|
||||
}
|
||||
|
||||
void NumberRangeFormatterTest::testPlurals() {
|
||||
|
|
|
@ -184,9 +184,11 @@ void NumberSkeletonTest::invalidTokens() {
|
|||
u"scientific/ee",
|
||||
u"precision-increment/xxx",
|
||||
u"precision-increment/NaN",
|
||||
u"precision-increment/Infinity",
|
||||
u"precision-increment/0.1.2",
|
||||
u"scale/xxx",
|
||||
u"scale/NaN",
|
||||
u"scale/Infinity",
|
||||
u"scale/0.1.2",
|
||||
u"scale/français", // non-invariant characters for C++
|
||||
u"currency/dummy",
|
||||
|
|
|
@ -167,9 +167,11 @@ public class NumberSkeletonTest {
|
|||
"scientific/ee",
|
||||
"precision-increment/xxx",
|
||||
"precision-increment/NaN",
|
||||
"precision-increment/Infinity",
|
||||
"precision-increment/0.1.2",
|
||||
"scale/xxx",
|
||||
"scale/NaN",
|
||||
"scale/Infinity",
|
||||
"scale/0.1.2",
|
||||
"scale/français", // non-invariant characters for C++
|
||||
"currency/dummy",
|
||||
|
|
Loading…
Add table
Reference in a new issue