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[] {