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();
}
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 {
#include "double-conversion.h"
#include "number_roundingutils.h"
#include "number_skeletons.h"
+#include "number_decnum.h"
#include "putilimp.h"
#include "string_segment.h"
// 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;
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;
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
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;
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));
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() {
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",
"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",