ICU-20709 Adding fourth signum type. Converting Java to use enum.
diff --git a/icu4c/source/i18n/number_decimalquantity.cpp b/icu4c/source/i18n/number_decimalquantity.cpp
index 2c4c2ce..abbc23d 100644
--- a/icu4c/source/i18n/number_decimalquantity.cpp
+++ b/icu4c/source/i18n/number_decimalquantity.cpp
@@ -319,10 +319,14 @@
}
Signum DecimalQuantity::signum() const {
- if (isNegative()) {
+ bool isZero = (isZeroish() && !isInfinite());
+ bool isNeg = isNegative();
+ if (isZero && isNeg) {
+ return SIGNUM_NEG_ZERO;
+ } else if (isZero) {
+ return SIGNUM_POS_ZERO;
+ } else if (isNeg) {
return SIGNUM_NEG;
- } else if (isZeroish() && !isInfinite()) {
- return SIGNUM_ZERO;
} else {
return SIGNUM_POS;
}
diff --git a/icu4c/source/i18n/number_longnames.cpp b/icu4c/source/i18n/number_longnames.cpp
index 817aa0e..5519398 100644
--- a/icu4c/source/i18n/number_longnames.cpp
+++ b/icu4c/source/i18n/number_longnames.cpp
@@ -308,7 +308,7 @@
if (U_FAILURE(status)) { return; }
SimpleFormatter compiledFormatter(simpleFormat, 0, 1, status);
if (U_FAILURE(status)) { return; }
- fModifiers[i] = SimpleModifier(compiledFormatter, field, false, {this, SIGNUM_ZERO, plural});
+ fModifiers[i] = SimpleModifier(compiledFormatter, field, false, {this, SIGNUM_POS_ZERO, plural});
}
}
@@ -325,7 +325,7 @@
if (U_FAILURE(status)) { return; }
SimpleFormatter compoundCompiled(compoundFormat, 0, 1, status);
if (U_FAILURE(status)) { return; }
- fModifiers[i] = SimpleModifier(compoundCompiled, field, false, {this, SIGNUM_ZERO, plural});
+ fModifiers[i] = SimpleModifier(compoundCompiled, field, false, {this, SIGNUM_POS_ZERO, plural});
}
}
diff --git a/icu4c/source/i18n/number_modifiers.h b/icu4c/source/i18n/number_modifiers.h
index c84c6aa..6fd0bad 100644
--- a/icu4c/source/i18n/number_modifiers.h
+++ b/icu4c/source/i18n/number_modifiers.h
@@ -319,12 +319,12 @@
private:
// NOTE: mods is zero-initialized (to nullptr)
- const Modifier *mods[3 * StandardPlural::COUNT] = {};
+ const Modifier *mods[4 * StandardPlural::COUNT] = {};
inline static int32_t getModIndex(Signum signum, StandardPlural::Form plural) {
- U_ASSERT(signum >= -1 && signum <= 1);
+ U_ASSERT(signum >= 0 && signum <= 3);
U_ASSERT(plural >= 0 && plural < StandardPlural::COUNT);
- return static_cast<int32_t>(plural) * 3 + (signum + 1);
+ return static_cast<int32_t>(plural) * 4 + signum;
}
};
diff --git a/icu4c/source/i18n/number_patternmodifier.cpp b/icu4c/source/i18n/number_patternmodifier.cpp
index 724f5b9..3599ba7 100644
--- a/icu4c/source/i18n/number_patternmodifier.cpp
+++ b/icu4c/source/i18n/number_patternmodifier.cpp
@@ -81,8 +81,10 @@
for (StandardPlural::Form plural : STANDARD_PLURAL_VALUES) {
setNumberProperties(SIGNUM_POS, plural);
pm->adoptModifier(SIGNUM_POS, plural, createConstantModifier(status));
- setNumberProperties(SIGNUM_ZERO, plural);
- pm->adoptModifier(SIGNUM_ZERO, plural, createConstantModifier(status));
+ setNumberProperties(SIGNUM_NEG_ZERO, plural);
+ pm->adoptModifier(SIGNUM_NEG_ZERO, plural, createConstantModifier(status));
+ setNumberProperties(SIGNUM_POS_ZERO, plural);
+ pm->adoptModifier(SIGNUM_POS_ZERO, plural, createConstantModifier(status));
setNumberProperties(SIGNUM_NEG, plural);
pm->adoptModifier(SIGNUM_NEG, plural, createConstantModifier(status));
}
@@ -95,8 +97,10 @@
// Faster path when plural keyword is not needed.
setNumberProperties(SIGNUM_POS, StandardPlural::Form::COUNT);
pm->adoptModifierWithoutPlural(SIGNUM_POS, createConstantModifier(status));
- setNumberProperties(SIGNUM_ZERO, StandardPlural::Form::COUNT);
- pm->adoptModifierWithoutPlural(SIGNUM_ZERO, createConstantModifier(status));
+ setNumberProperties(SIGNUM_NEG_ZERO, StandardPlural::Form::COUNT);
+ pm->adoptModifierWithoutPlural(SIGNUM_NEG_ZERO, createConstantModifier(status));
+ setNumberProperties(SIGNUM_POS_ZERO, StandardPlural::Form::COUNT);
+ pm->adoptModifierWithoutPlural(SIGNUM_POS_ZERO, createConstantModifier(status));
setNumberProperties(SIGNUM_NEG, StandardPlural::Form::COUNT);
pm->adoptModifierWithoutPlural(SIGNUM_NEG, createConstantModifier(status));
if (U_FAILURE(status)) {
@@ -263,7 +267,12 @@
/** This method contains the heart of the logic for rendering LDML affix strings. */
void MutablePatternModifier::prepareAffix(bool isPrefix) {
PatternStringUtils::patternInfoToStringBuilder(
- *fPatternInfo, isPrefix, fSignum, fSignDisplay, fPlural, fPerMilleReplacesPercent, currentAffix);
+ *fPatternInfo,
+ isPrefix,
+ PatternStringUtils::resolveSignDisplay(fSignDisplay, fSignum),
+ fPlural,
+ fPerMilleReplacesPercent,
+ currentAffix);
}
UnicodeString MutablePatternModifier::getSymbol(AffixPatternType type) const {
diff --git a/icu4c/source/i18n/number_patternstring.cpp b/icu4c/source/i18n/number_patternstring.cpp
index c7212c1..b2e6edc 100644
--- a/icu4c/source/i18n/number_patternstring.cpp
+++ b/icu4c/source/i18n/number_patternstring.cpp
@@ -1000,23 +1000,19 @@
}
void PatternStringUtils::patternInfoToStringBuilder(const AffixPatternProvider& patternInfo, bool isPrefix,
- Signum signum, UNumberSignDisplay signDisplay,
+ PatternSignType patternSignType,
StandardPlural::Form plural,
bool perMilleReplacesPercent, UnicodeString& output) {
// Should the output render '+' where '-' would normally appear in the pattern?
- bool plusReplacesMinusSign = signum != -1 && (
- signDisplay == UNUM_SIGN_ALWAYS || signDisplay == UNUM_SIGN_ACCOUNTING_ALWAYS || (
- signum == 1 && (
- signDisplay == UNUM_SIGN_EXCEPT_ZERO ||
- signDisplay == UNUM_SIGN_ACCOUNTING_EXCEPT_ZERO))) &&
- patternInfo.positiveHasPlusSign() == false;
+ bool plusReplacesMinusSign = (patternSignType == PATTERN_SIGN_TYPE_POS_SIGN)
+ && !patternInfo.positiveHasPlusSign();
- // Should we use the affix from the negative subpattern? (If not, we will use the positive
- // subpattern.)
- // TODO: Deal with signum
- bool useNegativeAffixPattern = patternInfo.hasNegativeSubpattern() && (
- signum == -1 || (patternInfo.negativeHasMinusSign() && plusReplacesMinusSign));
+ // Should we use the affix from the negative subpattern?
+ // (If not, we will use the positive subpattern.)
+ bool useNegativeAffixPattern = patternInfo.hasNegativeSubpattern()
+ && (patternSignType == PATTERN_SIGN_TYPE_NEG
+ || (patternInfo.negativeHasMinusSign() && plusReplacesMinusSign));
// Resolve the flags for the affix pattern.
int flags = 0;
@@ -1035,8 +1031,8 @@
bool prependSign;
if (!isPrefix || useNegativeAffixPattern) {
prependSign = false;
- } else if (signum == -1) {
- prependSign = signDisplay != UNUM_SIGN_NEVER;
+ } else if (patternSignType == PATTERN_SIGN_TYPE_NEG) {
+ prependSign = true;
} else {
prependSign = plusReplacesMinusSign;
}
@@ -1065,4 +1061,54 @@
}
}
+PatternSignType PatternStringUtils::resolveSignDisplay(UNumberSignDisplay signDisplay, Signum signum) {
+ switch (signDisplay) {
+ case UNUM_SIGN_AUTO:
+ case UNUM_SIGN_ACCOUNTING:
+ switch (signum) {
+ case SIGNUM_NEG:
+ case SIGNUM_NEG_ZERO:
+ return PATTERN_SIGN_TYPE_NEG;
+ case SIGNUM_POS_ZERO:
+ case SIGNUM_POS:
+ return PATTERN_SIGN_TYPE_POS;
+ }
+ break;
+
+ case UNUM_SIGN_ALWAYS:
+ case UNUM_SIGN_ACCOUNTING_ALWAYS:
+ switch (signum) {
+ case SIGNUM_NEG:
+ case SIGNUM_NEG_ZERO:
+ return PATTERN_SIGN_TYPE_NEG;
+ case SIGNUM_POS_ZERO:
+ case SIGNUM_POS:
+ return PATTERN_SIGN_TYPE_POS_SIGN;
+ }
+ break;
+
+ case UNUM_SIGN_EXCEPT_ZERO:
+ case UNUM_SIGN_ACCOUNTING_EXCEPT_ZERO:
+ switch (signum) {
+ case SIGNUM_NEG:
+ return PATTERN_SIGN_TYPE_NEG;
+ case SIGNUM_NEG_ZERO:
+ case SIGNUM_POS_ZERO:
+ return PATTERN_SIGN_TYPE_POS;
+ case SIGNUM_POS:
+ return PATTERN_SIGN_TYPE_POS_SIGN;
+ }
+ break;
+
+ case UNUM_SIGN_NEVER:
+ return PATTERN_SIGN_TYPE_POS;
+
+ default:
+ break;
+ }
+
+ UPRV_UNREACHABLE;
+ return PATTERN_SIGN_TYPE_POS;
+}
+
#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/icu4c/source/i18n/number_patternstring.h b/icu4c/source/i18n/number_patternstring.h
index 1191d29..54f37fd 100644
--- a/icu4c/source/i18n/number_patternstring.h
+++ b/icu4c/source/i18n/number_patternstring.h
@@ -22,6 +22,18 @@
// Forward declaration
class PatternParser;
+// Note: the order of fields in this enum matters for parsing.
+enum PatternSignType {
+ /** Render using normal positive subpattern rules */
+ PATTERN_SIGN_TYPE_POS,
+ /** Render using rules to force the display of a plus sign */
+ PATTERN_SIGN_TYPE_POS_SIGN,
+ /** Render using negative subpattern rules */
+ PATTERN_SIGN_TYPE_NEG,
+ /** Count for looping over the possibilities */
+ PATTERN_SIGN_TYPE_COUNT
+};
+
// Exported as U_I18N_API because it is a public member field of exported ParsedSubpatternInfo
struct U_I18N_API Endpoints {
int32_t start = 0;
@@ -295,10 +307,12 @@
* substitution, and plural forms for CurrencyPluralInfo.
*/
static void patternInfoToStringBuilder(const AffixPatternProvider& patternInfo, bool isPrefix,
- Signum signum, UNumberSignDisplay signDisplay,
+ PatternSignType patternSignType,
StandardPlural::Form plural, bool perMilleReplacesPercent,
UnicodeString& output);
+ static PatternSignType resolveSignDisplay(UNumberSignDisplay signDisplay, Signum signum);
+
private:
/** @return The number of chars inserted. */
static int escapePaddingString(UnicodeString input, UnicodeString& output, int startIndex,
diff --git a/icu4c/source/i18n/number_types.h b/icu4c/source/i18n/number_types.h
index d62aa6a..49b77ee 100644
--- a/icu4c/source/i18n/number_types.h
+++ b/icu4c/source/i18n/number_types.h
@@ -92,9 +92,10 @@
};
enum Signum {
- SIGNUM_NEG = -1,
- SIGNUM_ZERO = 0,
- SIGNUM_POS = 1
+ SIGNUM_NEG = 0,
+ SIGNUM_NEG_ZERO = 1,
+ SIGNUM_POS_ZERO = 2,
+ SIGNUM_POS = 3
};
diff --git a/icu4c/source/i18n/numparse_affixes.cpp b/icu4c/source/i18n/numparse_affixes.cpp
index cf8bab4..ca293e7 100644
--- a/icu4c/source/i18n/numparse_affixes.cpp
+++ b/icu4c/source/i18n/numparse_affixes.cpp
@@ -271,8 +271,6 @@
// Use initial capacity of 6, the highest possible number of AffixMatchers.
UnicodeString sb;
bool includeUnpaired = 0 != (parseFlags & PARSE_FLAG_INCLUDE_UNPAIRED_AFFIXES);
- UNumberSignDisplay signDisplay = (0 != (parseFlags & PARSE_FLAG_PLUS_SIGN_ALLOWED)) ? UNUM_SIGN_ALWAYS
- : UNUM_SIGN_AUTO;
int32_t numAffixMatchers = 0;
int32_t numAffixPatternMatchers = 0;
@@ -281,13 +279,23 @@
AffixPatternMatcher* posSuffix = nullptr;
// Pre-process the affix strings to resolve LDML rules like sign display.
- for (int8_t signumInt = 1; signumInt >= -1; signumInt--) {
- auto signum = static_cast<Signum>(signumInt);
+ for (int8_t typeInt = 0; typeInt < PATTERN_SIGN_TYPE_COUNT; typeInt++) {
+ auto type = static_cast<PatternSignType>(typeInt);
+
+ // Skip affixes in some cases
+ if (type == PATTERN_SIGN_TYPE_POS
+ && 0 != (parseFlags & PARSE_FLAG_PLUS_SIGN_ALLOWED)) {
+ continue;
+ }
+ if (type == PATTERN_SIGN_TYPE_POS_SIGN
+ && 0 == (parseFlags & PARSE_FLAG_PLUS_SIGN_ALLOWED)) {
+ continue;
+ }
// Generate Prefix
bool hasPrefix = false;
PatternStringUtils::patternInfoToStringBuilder(
- patternInfo, true, signum, signDisplay, StandardPlural::OTHER, false, sb);
+ patternInfo, true, type, StandardPlural::OTHER, false, sb);
fAffixPatternMatchers[numAffixPatternMatchers] = AffixPatternMatcher::fromAffixPattern(
sb, *fTokenWarehouse, parseFlags, &hasPrefix, status);
AffixPatternMatcher* prefix = hasPrefix ? &fAffixPatternMatchers[numAffixPatternMatchers++]
@@ -296,13 +304,13 @@
// Generate Suffix
bool hasSuffix = false;
PatternStringUtils::patternInfoToStringBuilder(
- patternInfo, false, signum, signDisplay, StandardPlural::OTHER, false, sb);
+ patternInfo, false, type, StandardPlural::OTHER, false, sb);
fAffixPatternMatchers[numAffixPatternMatchers] = AffixPatternMatcher::fromAffixPattern(
sb, *fTokenWarehouse, parseFlags, &hasSuffix, status);
AffixPatternMatcher* suffix = hasSuffix ? &fAffixPatternMatchers[numAffixPatternMatchers++]
: nullptr;
- if (signum == 1) {
+ if (type == PATTERN_SIGN_TYPE_POS) {
posPrefix = prefix;
posSuffix = suffix;
} else if (equals(prefix, posPrefix) && equals(suffix, posSuffix)) {
@@ -311,17 +319,17 @@
}
// Flags for setting in the ParsedNumber; the token matchers may add more.
- int flags = (signum == -1) ? FLAG_NEGATIVE : 0;
+ int flags = (type == PATTERN_SIGN_TYPE_NEG) ? FLAG_NEGATIVE : 0;
// Note: it is indeed possible for posPrefix and posSuffix to both be null.
// We still need to add that matcher for strict mode to work.
fAffixMatchers[numAffixMatchers++] = {prefix, suffix, flags};
if (includeUnpaired && prefix != nullptr && suffix != nullptr) {
// The following if statements are designed to prevent adding two identical matchers.
- if (signum == 1 || !equals(prefix, posPrefix)) {
+ if (type == PATTERN_SIGN_TYPE_POS || !equals(prefix, posPrefix)) {
fAffixMatchers[numAffixMatchers++] = {prefix, nullptr, flags};
}
- if (signum == 1 || !equals(suffix, posSuffix)) {
+ if (type == PATTERN_SIGN_TYPE_POS || !equals(suffix, posSuffix)) {
fAffixMatchers[numAffixMatchers++] = {nullptr, suffix, flags};
}
}
diff --git a/icu4c/source/test/intltest/numbertest_api.cpp b/icu4c/source/test/intltest/numbertest_api.cpp
index 4e4f0b7..726e7c5 100644
--- a/icu4c/source/test/intltest/numbertest_api.cpp
+++ b/icu4c/source/test/intltest/numbertest_api.cpp
@@ -2114,7 +2114,7 @@
{ UNUM_SIGN_AUTO, { u"-∞", u"-1", u"-0", u"0", u"1", u"∞", u"NaN", u"-NaN" } },
{ UNUM_SIGN_ALWAYS, { u"-∞", u"-1", u"-0", u"+0", u"+1", u"+∞", u"+NaN", u"-NaN" } },
{ UNUM_SIGN_NEVER, { u"∞", u"1", u"0", u"0", u"1", u"∞", u"NaN", u"NaN" } },
- { UNUM_SIGN_EXCEPT_ZERO, { u"-∞", u"-1", u"-0", u"0", u"+1", u"+∞", u"NaN", u"-NaN" } },
+ { UNUM_SIGN_EXCEPT_ZERO, { u"-∞", u"-1", u"0", u"0", u"+1", u"+∞", u"NaN", u"NaN" } },
};
double negNaN = std::copysign(uprv_getNaN(), -0.0);
const double inputs[] = {
diff --git a/icu4c/source/test/intltest/numbertest_patternmodifier.cpp b/icu4c/source/test/intltest/numbertest_patternmodifier.cpp
index 8f61242..1d1e634 100644
--- a/icu4c/source/test/intltest/numbertest_patternmodifier.cpp
+++ b/icu4c/source/test/intltest/numbertest_patternmodifier.cpp
@@ -41,7 +41,10 @@
mod.setPatternAttributes(UNUM_SIGN_ALWAYS, false);
assertEquals("Pattern a0b", u"+a", getPrefix(mod, status));
assertEquals("Pattern a0b", u"b", getSuffix(mod, status));
- mod.setNumberProperties(SIGNUM_ZERO, StandardPlural::Form::COUNT);
+ mod.setNumberProperties(SIGNUM_NEG_ZERO, StandardPlural::Form::COUNT);
+ assertEquals("Pattern a0b", u"-a", getPrefix(mod, status));
+ assertEquals("Pattern a0b", u"b", getSuffix(mod, status));
+ mod.setNumberProperties(SIGNUM_POS_ZERO, StandardPlural::Form::COUNT);
assertEquals("Pattern a0b", u"+a", getPrefix(mod, status));
assertEquals("Pattern a0b", u"b", getSuffix(mod, status));
mod.setPatternAttributes(UNUM_SIGN_EXCEPT_ZERO, false);
@@ -66,7 +69,10 @@
mod.setPatternAttributes(UNUM_SIGN_ALWAYS, false);
assertEquals("Pattern a0b;c-0d", u"c+", getPrefix(mod, status));
assertEquals("Pattern a0b;c-0d", u"d", getSuffix(mod, status));
- mod.setNumberProperties(SIGNUM_ZERO, StandardPlural::Form::COUNT);
+ mod.setNumberProperties(SIGNUM_NEG_ZERO, StandardPlural::Form::COUNT);
+ assertEquals("Pattern a0b;c-0d", u"c-", getPrefix(mod, status));
+ assertEquals("Pattern a0b;c-0d", u"d", getSuffix(mod, status));
+ mod.setNumberProperties(SIGNUM_POS_ZERO, StandardPlural::Form::COUNT);
assertEquals("Pattern a0b;c-0d", u"c+", getPrefix(mod, status));
assertEquals("Pattern a0b;c-0d", u"d", getSuffix(mod, status));
mod.setPatternAttributes(UNUM_SIGN_EXCEPT_ZERO, false);
@@ -76,9 +82,8 @@
assertEquals("Pattern a0b;c-0d", u"c-", getPrefix(mod, status));
assertEquals("Pattern a0b;c-0d", u"d", getSuffix(mod, status));
mod.setPatternAttributes(UNUM_SIGN_NEVER, false);
- // TODO: What should this behavior be?
- assertEquals("Pattern a0b;c-0d", u"c-", getPrefix(mod, status));
- assertEquals("Pattern a0b;c-0d", u"d", getSuffix(mod, status));
+ assertEquals("Pattern a0b;c-0d", u"a", getPrefix(mod, status));
+ assertEquals("Pattern a0b;c-0d", u"b", getSuffix(mod, status));
assertSuccess("Spot 5", status);
}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/AdoptingModifierStore.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/AdoptingModifierStore.java
index 7e3459d..8365248 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/AdoptingModifierStore.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/AdoptingModifierStore.java
@@ -3,6 +3,7 @@
package com.ibm.icu.impl.number;
import com.ibm.icu.impl.StandardPlural;
+import com.ibm.icu.impl.number.Modifier.Signum;
/**
* This implementation of ModifierStore adopts references to Modifiers.
@@ -11,7 +12,8 @@
*/
public class AdoptingModifierStore implements ModifierStore {
private final Modifier positive;
- private final Modifier zero;
+ private final Modifier posZero;
+ private final Modifier negZero;
private final Modifier negative;
final Modifier[] mods;
boolean frozen;
@@ -22,9 +24,10 @@
* <p>
* If this constructor is used, a plural form CANNOT be passed to {@link #getModifier}.
*/
- public AdoptingModifierStore(Modifier positive, Modifier zero, Modifier negative) {
+ public AdoptingModifierStore(Modifier positive, Modifier posZero, Modifier negZero, Modifier negative) {
this.positive = positive;
- this.zero = zero;
+ this.posZero = posZero;
+ this.negZero = negZero;
this.negative = negative;
this.mods = null;
this.frozen = true;
@@ -39,13 +42,14 @@
*/
public AdoptingModifierStore() {
this.positive = null;
- this.zero = null;
+ this.posZero = null;
+ this.negZero = null;
this.negative = null;
- this.mods = new Modifier[3 * StandardPlural.COUNT];
+ this.mods = new Modifier[4 * StandardPlural.COUNT];
this.frozen = false;
}
- public void setModifier(int signum, StandardPlural plural, Modifier mod) {
+ public void setModifier(Signum signum, StandardPlural plural, Modifier mod) {
assert !frozen;
mods[getModIndex(signum, plural)] = mod;
}
@@ -54,21 +58,34 @@
frozen = true;
}
- public Modifier getModifierWithoutPlural(int signum) {
+ public Modifier getModifierWithoutPlural(Signum signum) {
assert frozen;
assert mods == null;
- return signum == 0 ? zero : signum < 0 ? negative : positive;
+ assert signum != null;
+ switch (signum) {
+ case POS:
+ return positive;
+ case POS_ZERO:
+ return posZero;
+ case NEG_ZERO:
+ return negZero;
+ case NEG:
+ return negative;
+ default:
+ throw new AssertionError("Unreachable");
+ }
}
- public Modifier getModifier(int signum, StandardPlural plural) {
+ @Override
+ public Modifier getModifier(Signum signum, StandardPlural plural) {
assert frozen;
assert positive == null;
return mods[getModIndex(signum, plural)];
}
- private static int getModIndex(int signum, StandardPlural plural) {
- assert signum >= -1 && signum <= 1;
+ private static int getModIndex(Signum signum, StandardPlural plural) {
+ assert signum != null;
assert plural != null;
- return plural.ordinal() * 3 + (signum + 1);
+ return plural.ordinal() * 4 + signum.ordinal();
}
}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/DecimalQuantity.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/DecimalQuantity.java
index d551c32..7d30c58 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/DecimalQuantity.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/DecimalQuantity.java
@@ -7,6 +7,7 @@
import java.text.FieldPosition;
import com.ibm.icu.impl.StandardPlural;
+import com.ibm.icu.impl.number.Modifier.Signum;
import com.ibm.icu.text.PluralRules;
import com.ibm.icu.text.UFieldPosition;
@@ -130,8 +131,8 @@
/** @return Whether the value represented by this {@link DecimalQuantity} is less than zero. */
public boolean isNegative();
- /** @return -1 if the value is negative; 1 if positive; or 0 if zero. */
- public int signum();
+ /** @return The appropriate value from the Signum enum. */
+ public Signum signum();
/** @return Whether the value represented by this {@link DecimalQuantity} is infinite. */
@Override
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/DecimalQuantity_AbstractBCD.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/DecimalQuantity_AbstractBCD.java
index badc530..09c8893 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/DecimalQuantity_AbstractBCD.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/DecimalQuantity_AbstractBCD.java
@@ -9,6 +9,7 @@
import com.ibm.icu.impl.StandardPlural;
import com.ibm.icu.impl.Utility;
+import com.ibm.icu.impl.number.Modifier.Signum;
import com.ibm.icu.text.PluralRules;
import com.ibm.icu.text.PluralRules.Operand;
import com.ibm.icu.text.UFieldPosition;
@@ -303,8 +304,18 @@
}
@Override
- public int signum() {
- return isNegative() ? -1 : (isZeroish() && !isInfinite()) ? 0 : 1;
+ public Signum signum() {
+ boolean isZero = (isZeroish() && !isInfinite());
+ boolean isNeg = isNegative();
+ if (isZero && isNeg) {
+ return Signum.NEG_ZERO;
+ } else if (isZero) {
+ return Signum.POS_ZERO;
+ } else if (isNeg) {
+ return Signum.NEG;
+ } else {
+ return Signum.POS;
+ }
}
@Override
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/LongNameHandler.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/LongNameHandler.java
index c0c6a74..459e514 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/LongNameHandler.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/LongNameHandler.java
@@ -12,6 +12,7 @@
import com.ibm.icu.impl.SimpleFormatterImpl;
import com.ibm.icu.impl.StandardPlural;
import com.ibm.icu.impl.UResource;
+import com.ibm.icu.impl.number.Modifier.Signum;
import com.ibm.icu.number.NumberFormatter.UnitWidth;
import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.text.PluralRules;
@@ -262,7 +263,7 @@
String compiled = SimpleFormatterImpl.compileToStringMinMaxArguments(simpleFormat, sb, 0, 1);
Modifier.Parameters parameters = new Modifier.Parameters();
parameters.obj = this;
- parameters.signum = 0;
+ parameters.signum = null;// Signum ignored
parameters.plural = plural;
modifiers.put(plural, new SimpleModifier(compiled, field, false, parameters));
}
@@ -281,7 +282,7 @@
.compileToStringMinMaxArguments(compoundFormat, sb, 0, 1);
Modifier.Parameters parameters = new Modifier.Parameters();
parameters.obj = this;
- parameters.signum = 0;
+ parameters.signum = null; // Signum ignored
parameters.plural = plural;
modifiers.put(plural, new SimpleModifier(compoundCompiled, field, false, parameters));
}
@@ -296,7 +297,8 @@
}
@Override
- public Modifier getModifier(int signum, StandardPlural plural) {
+ public Modifier getModifier(Signum signum, StandardPlural plural) {
+ // Signum ignored
return modifiers.get(plural);
}
}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/Modifier.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/Modifier.java
index cc56329..43542e1 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/Modifier.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/Modifier.java
@@ -17,6 +17,13 @@
*/
public interface Modifier {
+ static enum Signum {
+ NEG,
+ NEG_ZERO,
+ POS_ZERO,
+ POS
+ };
+
/**
* Apply this Modifier to the string builder.
*
@@ -65,7 +72,7 @@
*/
public static class Parameters {
public ModifierStore obj;
- public int signum;
+ public Signum signum;
public StandardPlural plural;
}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/ModifierStore.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/ModifierStore.java
index 1751c1c..2546cf2 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/ModifierStore.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/ModifierStore.java
@@ -3,6 +3,7 @@
package com.ibm.icu.impl.number;
import com.ibm.icu.impl.StandardPlural;
+import com.ibm.icu.impl.number.Modifier.Signum;
/**
* This is *not* a modifier; rather, it is an object that can return modifiers
@@ -14,5 +15,5 @@
/**
* Returns a Modifier with the given parameters (best-effort).
*/
- Modifier getModifier(int signum, StandardPlural plural);
+ Modifier getModifier(Signum signum, StandardPlural plural);
}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/MutablePatternModifier.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/MutablePatternModifier.java
index 67f79b9..ebf30f6 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/MutablePatternModifier.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/MutablePatternModifier.java
@@ -50,7 +50,7 @@
PluralRules rules;
// Number details
- int signum;
+ Signum signum;
StandardPlural plural;
// QuantityChain details
@@ -129,7 +129,7 @@
* The plural form of the number, required only if the pattern contains the triple
* currency sign, "¤¤¤" (and as indicated by {@link #needsPlurals()}).
*/
- public void setNumberProperties(int signum, StandardPlural plural) {
+ public void setNumberProperties(Signum signum, StandardPlural plural) {
assert (plural != null) == needsPlurals();
this.signum = signum;
this.plural = plural;
@@ -174,24 +174,28 @@
// Slower path when we require the plural keyword.
AdoptingModifierStore pm = new AdoptingModifierStore();
for (StandardPlural plural : StandardPlural.VALUES) {
- setNumberProperties(1, plural);
- pm.setModifier(1, plural, createConstantModifier(a, b));
- setNumberProperties(0, plural);
- pm.setModifier(0, plural, createConstantModifier(a, b));
- setNumberProperties(-1, plural);
- pm.setModifier(-1, plural, createConstantModifier(a, b));
+ setNumberProperties(Signum.POS, plural);
+ pm.setModifier(Signum.POS, plural, createConstantModifier(a, b));
+ setNumberProperties(Signum.POS_ZERO, plural);
+ pm.setModifier(Signum.POS_ZERO, plural, createConstantModifier(a, b));
+ setNumberProperties(Signum.NEG_ZERO, plural);
+ pm.setModifier(Signum.NEG_ZERO, plural, createConstantModifier(a, b));
+ setNumberProperties(Signum.NEG, plural);
+ pm.setModifier(Signum.NEG, plural, createConstantModifier(a, b));
}
pm.freeze();
return new ImmutablePatternModifier(pm, rules, parent);
} else {
// Faster path when plural keyword is not needed.
- setNumberProperties(1, null);
+ setNumberProperties(Signum.POS, null);
Modifier positive = createConstantModifier(a, b);
- setNumberProperties(0, null);
- Modifier zero = createConstantModifier(a, b);
- setNumberProperties(-1, null);
+ setNumberProperties(Signum.POS_ZERO, null);
+ Modifier posZero = createConstantModifier(a, b);
+ setNumberProperties(Signum.NEG_ZERO, null);
+ Modifier negZero = createConstantModifier(a, b);
+ setNumberProperties(Signum.NEG, null);
Modifier negative = createConstantModifier(a, b);
- AdoptingModifierStore pm = new AdoptingModifierStore(positive, zero, negative);
+ AdoptingModifierStore pm = new AdoptingModifierStore(positive, posZero, negZero, negative);
return new ImmutablePatternModifier(pm, null, parent);
}
}
@@ -367,8 +371,7 @@
}
PatternStringUtils.patternInfoToStringBuilder(patternInfo,
isPrefix,
- signum,
- signDisplay,
+ PatternStringUtils.resolveSignDisplay(signDisplay, signum),
plural,
perMilleReplacesPercent,
currentAffix);
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/PatternStringUtils.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/PatternStringUtils.java
index 26eb457..601f1c8 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/PatternStringUtils.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/PatternStringUtils.java
@@ -5,6 +5,7 @@
import java.math.BigDecimal;
import com.ibm.icu.impl.StandardPlural;
+import com.ibm.icu.impl.number.Modifier.Signum;
import com.ibm.icu.impl.number.Padder.PadPosition;
import com.ibm.icu.number.NumberFormatter.SignDisplay;
import com.ibm.icu.text.DecimalFormatSymbols;
@@ -14,6 +15,18 @@
*/
public class PatternStringUtils {
+ // Note: the order of fields in this enum matters for parsing.
+ public static enum PatternSignType {
+ // Render using normal positive subpattern rules
+ POS,
+ // Render using rules to force the display of a plus sign
+ POS_SIGN,
+ // Render using negative subpattern rules
+ NEG;
+
+ public static final PatternSignType[] VALUES = PatternSignType.values();
+ };
+
/**
* Determine whether a given roundingIncrement should be ignored for formatting
* based on the current maxFrac value (maximum fraction digits). For example a
@@ -23,7 +36,7 @@
* it should not be ignored if maxFrac is 2 or more (but a roundingIncrement of
* 0.005 is treated like 0.001 for significance).
*
- * This test is needed for both NumberPropertyMapper.oldToNew and
+ * This test is needed for both NumberPropertyMapper.oldToNew and
* PatternStringUtils.propertiesToPatternString, but NumberPropertyMapper
* is package-private so we have it here.
*
@@ -416,25 +429,19 @@
public static void patternInfoToStringBuilder(
AffixPatternProvider patternInfo,
boolean isPrefix,
- int signum,
- SignDisplay signDisplay,
+ PatternSignType patternSignType,
StandardPlural plural,
boolean perMilleReplacesPercent,
StringBuilder output) {
- // Should the output render '+' where '-' would normally appear in the pattern?
- boolean plusReplacesMinusSign = signum != -1
- && (signDisplay == SignDisplay.ALWAYS
- || signDisplay == SignDisplay.ACCOUNTING_ALWAYS
- || (signum == 1
- && (signDisplay == SignDisplay.EXCEPT_ZERO
- || signDisplay == SignDisplay.ACCOUNTING_EXCEPT_ZERO)))
- && patternInfo.positiveHasPlusSign() == false;
+ boolean plusReplacesMinusSign = (patternSignType == PatternSignType.POS_SIGN)
+ && !patternInfo.positiveHasPlusSign();
- // Should we use the affix from the negative subpattern? (If not, we will use the positive
- // subpattern.)
+ // Should we use the affix from the negative subpattern?
+ // (If not, we will use the positive subpattern.)
boolean useNegativeAffixPattern = patternInfo.hasNegativeSubpattern()
- && (signum == -1 || (patternInfo.negativeHasMinusSign() && plusReplacesMinusSign));
+ && (patternSignType == PatternSignType.NEG
+ || (patternInfo.negativeHasMinusSign() && plusReplacesMinusSign));
// Resolve the flags for the affix pattern.
int flags = 0;
@@ -453,8 +460,8 @@
boolean prependSign;
if (!isPrefix || useNegativeAffixPattern) {
prependSign = false;
- } else if (signum == -1) {
- prependSign = signDisplay != SignDisplay.NEVER;
+ } else if (patternSignType == PatternSignType.NEG) {
+ prependSign = true;
} else {
prependSign = plusReplacesMinusSign;
}
@@ -483,4 +490,53 @@
}
}
+ public static PatternSignType resolveSignDisplay(SignDisplay signDisplay, Signum signum) {
+ switch (signDisplay) {
+ case AUTO:
+ case ACCOUNTING:
+ switch (signum) {
+ case NEG:
+ case NEG_ZERO:
+ return PatternSignType.NEG;
+ case POS_ZERO:
+ case POS:
+ return PatternSignType.POS;
+ }
+ break;
+
+ case ALWAYS:
+ case ACCOUNTING_ALWAYS:
+ switch (signum) {
+ case NEG:
+ case NEG_ZERO:
+ return PatternSignType.NEG;
+ case POS_ZERO:
+ case POS:
+ return PatternSignType.POS_SIGN;
+ }
+ break;
+
+ case EXCEPT_ZERO:
+ case ACCOUNTING_EXCEPT_ZERO:
+ switch (signum) {
+ case NEG:
+ return PatternSignType.NEG;
+ case NEG_ZERO:
+ case POS_ZERO:
+ return PatternSignType.POS;
+ case POS:
+ return PatternSignType.POS_SIGN;
+ }
+ break;
+
+ case NEVER:
+ return PatternSignType.POS;
+
+ default:
+ break;
+ }
+
+ throw new AssertionError("Unreachable");
+ }
+
}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/AffixMatcher.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/AffixMatcher.java
index 4292504..51b8df0 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/AffixMatcher.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/AffixMatcher.java
@@ -12,7 +12,7 @@
import com.ibm.icu.impl.number.AffixPatternProvider;
import com.ibm.icu.impl.number.AffixUtils;
import com.ibm.icu.impl.number.PatternStringUtils;
-import com.ibm.icu.number.NumberFormatter.SignDisplay;
+import com.ibm.icu.impl.number.PatternStringUtils.PatternSignType;
/**
* @author sffc
@@ -90,20 +90,27 @@
StringBuilder sb = new StringBuilder();
ArrayList<AffixMatcher> matchers = new ArrayList<>(6);
boolean includeUnpaired = 0 != (parseFlags & ParsingUtils.PARSE_FLAG_INCLUDE_UNPAIRED_AFFIXES);
- SignDisplay signDisplay = (0 != (parseFlags & ParsingUtils.PARSE_FLAG_PLUS_SIGN_ALLOWED))
- ? SignDisplay.ALWAYS
- : SignDisplay.AUTO;
AffixPatternMatcher posPrefix = null;
AffixPatternMatcher posSuffix = null;
// Pre-process the affix strings to resolve LDML rules like sign display.
- for (int signum = 1; signum >= -1; signum--) {
+ for (PatternSignType type : PatternSignType.VALUES) {
+
+ // Skip affixes in some cases
+ if (type == PatternSignType.POS
+ && 0 != (parseFlags & ParsingUtils.PARSE_FLAG_PLUS_SIGN_ALLOWED)) {
+ continue;
+ }
+ if (type == PatternSignType.POS_SIGN
+ && 0 == (parseFlags & ParsingUtils.PARSE_FLAG_PLUS_SIGN_ALLOWED)) {
+ continue;
+ }
+
// Generate Prefix
PatternStringUtils.patternInfoToStringBuilder(patternInfo,
true,
- signum,
- signDisplay,
+ type,
StandardPlural.OTHER,
false,
sb);
@@ -113,15 +120,14 @@
// Generate Suffix
PatternStringUtils.patternInfoToStringBuilder(patternInfo,
false,
- signum,
- signDisplay,
+ type,
StandardPlural.OTHER,
false,
sb);
AffixPatternMatcher suffix = AffixPatternMatcher
.fromAffixPattern(sb.toString(), factory, parseFlags);
- if (signum == 1) {
+ if (type == PatternSignType.POS) {
posPrefix = prefix;
posSuffix = suffix;
} else if (Objects.equals(prefix, posPrefix) && Objects.equals(suffix, posSuffix)) {
@@ -130,17 +136,17 @@
}
// Flags for setting in the ParsedNumber; the token matchers may add more.
- int flags = (signum == -1) ? ParsedNumber.FLAG_NEGATIVE : 0;
+ int flags = (type == PatternSignType.NEG) ? ParsedNumber.FLAG_NEGATIVE : 0;
// Note: it is indeed possible for posPrefix and posSuffix to both be null.
// We still need to add that matcher for strict mode to work.
matchers.add(getInstance(prefix, suffix, flags));
if (includeUnpaired && prefix != null && suffix != null) {
// The following if statements are designed to prevent adding two identical matchers.
- if (signum == 1 || !Objects.equals(prefix, posPrefix)) {
+ if (type == PatternSignType.POS || !Objects.equals(prefix, posPrefix)) {
matchers.add(getInstance(prefix, null, flags));
}
- if (signum == 1 || !Objects.equals(suffix, posSuffix)) {
+ if (type == PatternSignType.POS || !Objects.equals(suffix, posSuffix)) {
matchers.add(getInstance(null, suffix, flags));
}
}
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/impl/number/DecimalQuantity_SimpleStorage.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/impl/number/DecimalQuantity_SimpleStorage.java
index d8aae25..cb1bc57 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/impl/number/DecimalQuantity_SimpleStorage.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/impl/number/DecimalQuantity_SimpleStorage.java
@@ -9,6 +9,7 @@
import com.ibm.icu.impl.StandardPlural;
import com.ibm.icu.impl.number.DecimalQuantity;
+import com.ibm.icu.impl.number.Modifier.Signum;
import com.ibm.icu.text.PluralRules;
import com.ibm.icu.text.PluralRules.Operand;
import com.ibm.icu.text.UFieldPosition;
@@ -517,8 +518,18 @@
}
@Override
- public int signum() {
- return isNegative() ? -1 : isZeroish() ? 0 : 1;
+ public Signum signum() {
+ boolean isZero = (isZeroish() && !isInfinite());
+ boolean isNeg = isNegative();
+ if (isZero && isNeg) {
+ return Signum.NEG_ZERO;
+ } else if (isZero) {
+ return Signum.POS_ZERO;
+ } else if (isNeg) {
+ return Signum.NEG;
+ } else {
+ return Signum.POS;
+ }
}
private void setNegative(boolean isNegative) {
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/MutablePatternModifierTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/MutablePatternModifierTest.java
index 9f8585b..180919c 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/MutablePatternModifierTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/MutablePatternModifierTest.java
@@ -12,6 +12,7 @@
import com.ibm.icu.impl.number.DecimalQuantity;
import com.ibm.icu.impl.number.DecimalQuantity_DualStorageBCD;
import com.ibm.icu.impl.number.MicroProps;
+import com.ibm.icu.impl.number.Modifier.Signum;
import com.ibm.icu.impl.number.MutablePatternModifier;
import com.ibm.icu.impl.number.PatternStringParser;
import com.ibm.icu.number.NumberFormatter.SignDisplay;
@@ -32,19 +33,22 @@
UnitWidth.SHORT,
null);
- mod.setNumberProperties(1, null);
+ mod.setNumberProperties(Signum.POS, null);
assertEquals("a", getPrefix(mod));
assertEquals("b", getSuffix(mod));
mod.setPatternAttributes(SignDisplay.ALWAYS, false);
assertEquals("+a", getPrefix(mod));
assertEquals("b", getSuffix(mod));
- mod.setNumberProperties(0, null);
+ mod.setNumberProperties(Signum.POS_ZERO, null);
assertEquals("+a", getPrefix(mod));
assertEquals("b", getSuffix(mod));
+ mod.setNumberProperties(Signum.NEG_ZERO, null);
+ assertEquals("-a", getPrefix(mod));
+ assertEquals("b", getSuffix(mod));
mod.setPatternAttributes(SignDisplay.EXCEPT_ZERO, false);
assertEquals("a", getPrefix(mod));
assertEquals("b", getSuffix(mod));
- mod.setNumberProperties(-1, null);
+ mod.setNumberProperties(Signum.NEG, null);
assertEquals("-a", getPrefix(mod));
assertEquals("b", getSuffix(mod));
mod.setPatternAttributes(SignDisplay.NEVER, false);
@@ -53,24 +57,27 @@
mod.setPatternInfo(PatternStringParser.parseToPatternInfo("a0b;c-0d"), null);
mod.setPatternAttributes(SignDisplay.AUTO, false);
- mod.setNumberProperties(1, null);
+ mod.setNumberProperties(Signum.POS, null);
assertEquals("a", getPrefix(mod));
assertEquals("b", getSuffix(mod));
mod.setPatternAttributes(SignDisplay.ALWAYS, false);
assertEquals("c+", getPrefix(mod));
assertEquals("d", getSuffix(mod));
- mod.setNumberProperties(0, null);
+ mod.setNumberProperties(Signum.POS_ZERO, null);
assertEquals("c+", getPrefix(mod));
assertEquals("d", getSuffix(mod));
+ mod.setNumberProperties(Signum.NEG_ZERO, null);
+ assertEquals("c-", getPrefix(mod));
+ assertEquals("d", getSuffix(mod));
mod.setPatternAttributes(SignDisplay.EXCEPT_ZERO, false);
assertEquals("a", getPrefix(mod));
assertEquals("b", getSuffix(mod));
- mod.setNumberProperties(-1, null);
+ mod.setNumberProperties(Signum.NEG, null);
assertEquals("c-", getPrefix(mod));
assertEquals("d", getSuffix(mod));
mod.setPatternAttributes(SignDisplay.NEVER, false);
- assertEquals("c-", getPrefix(mod)); // TODO: What should this behavior be?
- assertEquals("d", getSuffix(mod));
+ assertEquals("a", getPrefix(mod));
+ assertEquals("b", getSuffix(mod));
}
@Test
@@ -112,7 +119,7 @@
Currency.getInstance("USD"),
UnitWidth.SHORT,
null);
- mod.setNumberProperties(1, null);
+ mod.setNumberProperties(Signum.POS_ZERO, null);
// Unsafe Code Path
FormattedStringBuilder nsb = new FormattedStringBuilder();
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java
index e5a872c..dbbf464 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java
@@ -2036,7 +2036,7 @@
{ {SignDisplay.AUTO}, { "-∞", "-1", "-0", "0", "1", "∞", "NaN", "-NaN" } },
{ {SignDisplay.ALWAYS}, { "-∞", "-1", "-0", "+0", "+1", "+∞", "+NaN", "-NaN" } },
{ {SignDisplay.NEVER}, { "∞", "1", "0", "0", "1", "∞", "NaN", "NaN" } },
- { {SignDisplay.EXCEPT_ZERO}, { "-∞", "-1", "-0", "0", "+1", "+∞", "NaN", "-NaN" } },
+ { {SignDisplay.EXCEPT_ZERO}, { "-∞", "-1", "0", "0", "+1", "+∞", "NaN", "NaN" } },
};
double negNaN = Math.copySign(Double.NaN, -0.0);
double inputs[] = new double[] {