mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-13 08:53:20 +00:00
ICU-2334 add public set/isSignificantDigits API; add min/max/useSignificantDigits fields
X-SVN-Rev: 14849
This commit is contained in:
parent
c36d609f8b
commit
8cc0c7011e
2 changed files with 145 additions and 110 deletions
|
@ -134,7 +134,10 @@ DecimalFormat::DecimalFormat(UErrorCode& status)
|
|||
fMinExponentDigits(0),
|
||||
fRoundingIncrement(0),
|
||||
fPad(0),
|
||||
fFormatWidth(0)
|
||||
fFormatWidth(0),
|
||||
fMinSignificantDigits(1),
|
||||
fMaxSignificantDigits(6),
|
||||
fUseSignificantDigits(FALSE)
|
||||
{
|
||||
UParseError parseError;
|
||||
construct(status, parseError);
|
||||
|
@ -159,7 +162,10 @@ DecimalFormat::DecimalFormat(const UnicodeString& pattern,
|
|||
fMinExponentDigits(0),
|
||||
fRoundingIncrement(0),
|
||||
fPad(0),
|
||||
fFormatWidth(0)
|
||||
fFormatWidth(0),
|
||||
fMinSignificantDigits(1),
|
||||
fMaxSignificantDigits(6),
|
||||
fUseSignificantDigits(FALSE)
|
||||
{
|
||||
UParseError parseError;
|
||||
construct(status, parseError, &pattern);
|
||||
|
@ -186,7 +192,10 @@ DecimalFormat::DecimalFormat(const UnicodeString& pattern,
|
|||
fMinExponentDigits(0),
|
||||
fRoundingIncrement(0),
|
||||
fPad(0),
|
||||
fFormatWidth(0)
|
||||
fFormatWidth(0),
|
||||
fMinSignificantDigits(1),
|
||||
fMaxSignificantDigits(6),
|
||||
fUseSignificantDigits(FALSE)
|
||||
{
|
||||
UParseError parseError;
|
||||
if (symbolsToAdopt == NULL)
|
||||
|
@ -211,7 +220,10 @@ DecimalFormat::DecimalFormat( const UnicodeString& pattern,
|
|||
fMinExponentDigits(0),
|
||||
fRoundingIncrement(0),
|
||||
fPad(0),
|
||||
fFormatWidth(0)
|
||||
fFormatWidth(0),
|
||||
fMinSignificantDigits(1),
|
||||
fMaxSignificantDigits(6),
|
||||
fUseSignificantDigits(FALSE)
|
||||
{
|
||||
if (symbolsToAdopt == NULL)
|
||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
|
@ -238,7 +250,10 @@ DecimalFormat::DecimalFormat(const UnicodeString& pattern,
|
|||
fMinExponentDigits(0),
|
||||
fRoundingIncrement(0),
|
||||
fPad(0),
|
||||
fFormatWidth(0)
|
||||
fFormatWidth(0),
|
||||
fMinSignificantDigits(1),
|
||||
fMaxSignificantDigits(6),
|
||||
fUseSignificantDigits(FALSE)
|
||||
{
|
||||
UParseError parseError;
|
||||
construct(status, parseError, &pattern, new DecimalFormatSymbols(symbols));
|
||||
|
@ -381,57 +396,61 @@ static void _copy_us_ptr(UnicodeString** pdest, const UnicodeString* source) {
|
|||
DecimalFormat&
|
||||
DecimalFormat::operator=(const DecimalFormat& rhs)
|
||||
{
|
||||
if(this != &rhs) {
|
||||
NumberFormat::operator=(rhs);
|
||||
fPositivePrefix = rhs.fPositivePrefix;
|
||||
fPositiveSuffix = rhs.fPositiveSuffix;
|
||||
fNegativePrefix = rhs.fNegativePrefix;
|
||||
fNegativeSuffix = rhs.fNegativeSuffix;
|
||||
_copy_us_ptr(&fPosPrefixPattern, rhs.fPosPrefixPattern);
|
||||
_copy_us_ptr(&fPosSuffixPattern, rhs.fPosSuffixPattern);
|
||||
_copy_us_ptr(&fNegPrefixPattern, rhs.fNegPrefixPattern);
|
||||
_copy_us_ptr(&fNegSuffixPattern, rhs.fNegSuffixPattern);
|
||||
if (rhs.fCurrencyChoice == 0) {
|
||||
delete fCurrencyChoice;
|
||||
fCurrencyChoice = 0;
|
||||
} else {
|
||||
fCurrencyChoice = (ChoiceFormat*) rhs.fCurrencyChoice->clone();
|
||||
}
|
||||
if(rhs.fRoundingIncrement == NULL) {
|
||||
delete fRoundingIncrement;
|
||||
fRoundingIncrement = NULL;
|
||||
}
|
||||
else if(fRoundingIncrement == NULL) {
|
||||
fRoundingIncrement = new DigitList(*rhs.fRoundingIncrement);
|
||||
}
|
||||
else {
|
||||
*fRoundingIncrement = *rhs.fRoundingIncrement;
|
||||
}
|
||||
fRoundingDouble = rhs.fRoundingDouble;
|
||||
fMultiplier = rhs.fMultiplier;
|
||||
fGroupingSize = rhs.fGroupingSize;
|
||||
fGroupingSize2 = rhs.fGroupingSize2;
|
||||
fDecimalSeparatorAlwaysShown = rhs.fDecimalSeparatorAlwaysShown;
|
||||
if(fSymbols == NULL)
|
||||
fSymbols = new DecimalFormatSymbols(*rhs.fSymbols);
|
||||
else
|
||||
*fSymbols = *rhs.fSymbols;
|
||||
fUseExponentialNotation = rhs.fUseExponentialNotation;
|
||||
fExponentSignAlwaysShown = rhs.fExponentSignAlwaysShown;
|
||||
/*Bertrand A. D. Update 98.03.17*/
|
||||
fIsCurrencyFormat = rhs.fIsCurrencyFormat;
|
||||
/*end of Update*/
|
||||
fMinExponentDigits = rhs.fMinExponentDigits;
|
||||
// if (fDigitList == NULL)
|
||||
// fDigitList = new DigitList();
|
||||
if(this != &rhs) {
|
||||
NumberFormat::operator=(rhs);
|
||||
fPositivePrefix = rhs.fPositivePrefix;
|
||||
fPositiveSuffix = rhs.fPositiveSuffix;
|
||||
fNegativePrefix = rhs.fNegativePrefix;
|
||||
fNegativeSuffix = rhs.fNegativeSuffix;
|
||||
_copy_us_ptr(&fPosPrefixPattern, rhs.fPosPrefixPattern);
|
||||
_copy_us_ptr(&fPosSuffixPattern, rhs.fPosSuffixPattern);
|
||||
_copy_us_ptr(&fNegPrefixPattern, rhs.fNegPrefixPattern);
|
||||
_copy_us_ptr(&fNegSuffixPattern, rhs.fNegSuffixPattern);
|
||||
if (rhs.fCurrencyChoice == 0) {
|
||||
delete fCurrencyChoice;
|
||||
fCurrencyChoice = 0;
|
||||
} else {
|
||||
fCurrencyChoice = (ChoiceFormat*) rhs.fCurrencyChoice->clone();
|
||||
}
|
||||
if(rhs.fRoundingIncrement == NULL) {
|
||||
delete fRoundingIncrement;
|
||||
fRoundingIncrement = NULL;
|
||||
}
|
||||
else if(fRoundingIncrement == NULL) {
|
||||
fRoundingIncrement = new DigitList(*rhs.fRoundingIncrement);
|
||||
}
|
||||
else {
|
||||
*fRoundingIncrement = *rhs.fRoundingIncrement;
|
||||
}
|
||||
fRoundingDouble = rhs.fRoundingDouble;
|
||||
fMultiplier = rhs.fMultiplier;
|
||||
fGroupingSize = rhs.fGroupingSize;
|
||||
fGroupingSize2 = rhs.fGroupingSize2;
|
||||
fDecimalSeparatorAlwaysShown = rhs.fDecimalSeparatorAlwaysShown;
|
||||
if(fSymbols == NULL) {
|
||||
fSymbols = new DecimalFormatSymbols(*rhs.fSymbols);
|
||||
} else {
|
||||
*fSymbols = *rhs.fSymbols;
|
||||
}
|
||||
fUseExponentialNotation = rhs.fUseExponentialNotation;
|
||||
fExponentSignAlwaysShown = rhs.fExponentSignAlwaysShown;
|
||||
/*Bertrand A. D. Update 98.03.17*/
|
||||
fIsCurrencyFormat = rhs.fIsCurrencyFormat;
|
||||
/*end of Update*/
|
||||
fMinExponentDigits = rhs.fMinExponentDigits;
|
||||
// if (fDigitList == NULL)
|
||||
// fDigitList = new DigitList();
|
||||
|
||||
/* sfb 990629 */
|
||||
fFormatWidth = rhs.fFormatWidth;
|
||||
fPad = rhs.fPad;
|
||||
fPadPosition = rhs.fPadPosition;
|
||||
/* end sfb */
|
||||
}
|
||||
return *this;
|
||||
/* sfb 990629 */
|
||||
fFormatWidth = rhs.fFormatWidth;
|
||||
fPad = rhs.fPad;
|
||||
fPadPosition = rhs.fPadPosition;
|
||||
/* end sfb */
|
||||
fMinSignificantDigits = rhs.fMinSignificantDigits;
|
||||
fMinSignificantDigits = rhs.fMaxSignificantDigits;
|
||||
fUseSignificantDigits = rhs.fUseSignificantDigits;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -547,6 +566,7 @@ DecimalFormat::operator==(const Format& that) const
|
|||
if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
|
||||
debug("Symbols !=");
|
||||
}
|
||||
// TODO Add debug stuff for significant digits here
|
||||
if (!first) { printf(" ]"); }
|
||||
#endif
|
||||
|
||||
|
@ -578,7 +598,11 @@ DecimalFormat::operator==(const Format& that) const
|
|||
fUseExponentialNotation == other->fUseExponentialNotation &&
|
||||
(!fUseExponentialNotation ||
|
||||
fMinExponentDigits == other->fMinExponentDigits) &&
|
||||
*fSymbols == *(other->fSymbols));
|
||||
*fSymbols == *(other->fSymbols) &&
|
||||
fUseSignificantDigits == other->fUseSignificantDigits &&
|
||||
(!fUseSignificantDigits ||
|
||||
(fMinSignificantDigits == other->fMinSignificantDigits &&
|
||||
fMaxSignificantDigits == other->fMaxSignificantDigits)));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -627,7 +651,7 @@ DecimalFormat::format(int64_t number,
|
|||
{
|
||||
digits.set(((double)number) * fMultiplier,
|
||||
precision(FALSE),
|
||||
!fUseExponentialNotation && !useSignificantDigits());
|
||||
!fUseExponentialNotation && !isSignificantDigits());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -716,7 +740,7 @@ DecimalFormat::format( double number,
|
|||
|
||||
// This detects negativity too.
|
||||
digits.set(number, precision(FALSE),
|
||||
!fUseExponentialNotation && !useSignificantDigits());
|
||||
!fUseExponentialNotation && !isSignificantDigits());
|
||||
|
||||
return subformat(appendTo, fieldPosition, digits, FALSE);
|
||||
}
|
||||
|
@ -809,7 +833,7 @@ DecimalFormat::subformat(UnicodeString& appendTo,
|
|||
} else {
|
||||
decimal = &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
|
||||
}
|
||||
UBool useSigDig = useSignificantDigits();
|
||||
UBool useSigDig = isSignificantDigits();
|
||||
int32_t maxIntDig = getMaximumIntegerDigits();
|
||||
int32_t minIntDig = getMinimumIntegerDigits();
|
||||
|
||||
|
@ -978,6 +1002,7 @@ DecimalFormat::subformat(UnicodeString& appendTo,
|
|||
int32_t minSigDig = getMinimumSignificantDigits();
|
||||
int32_t maxSigDig = getMaximumSignificantDigits();
|
||||
if (!useSigDig) {
|
||||
minSigDig = 0;
|
||||
maxSigDig = INT32_MAX;
|
||||
}
|
||||
|
||||
|
@ -2626,7 +2651,7 @@ DecimalFormat::toPattern(UnicodeString& result, UBool localized) const
|
|||
UnicodeString roundingDigits;
|
||||
int32_t padPos = (fFormatWidth > 0) ? fPadPosition : -1;
|
||||
UnicodeString padSpec;
|
||||
UBool useSigDig = useSignificantDigits();
|
||||
UBool useSigDig = isSignificantDigits();
|
||||
if (useSigDig) {
|
||||
sigDigit = localized ? getConstSymbol(DecimalFormatSymbols::kSignificantDigitSymbol).char32At(0) :
|
||||
kPatternSignificantDigit;
|
||||
|
@ -3324,13 +3349,15 @@ DecimalFormat::applyPattern(const UnicodeString& pattern,
|
|||
}
|
||||
fExponentSignAlwaysShown = expSignAlways;
|
||||
fIsCurrencyFormat = isCurrency;
|
||||
int digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount;
|
||||
int32_t digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount;
|
||||
// The effectiveDecimalPos is the position the decimal is at or
|
||||
// would be at if there is no decimal. Note that if
|
||||
// decimalPos<0, then digitTotalCount == digitLeftCount +
|
||||
// zeroDigitCount.
|
||||
int effectiveDecimalPos = decimalPos >= 0 ? decimalPos : digitTotalCount;
|
||||
if (sigDigitCount > 0) {
|
||||
int32_t effectiveDecimalPos = decimalPos >= 0 ? decimalPos : digitTotalCount;
|
||||
UBool isSigDig = (sigDigitCount > 0);
|
||||
setSignificantDigits(isSigDig);
|
||||
if (isSigDig) {
|
||||
setMinimumSignificantDigits(sigDigitCount);
|
||||
setMaximumSignificantDigits(sigDigitCount + digitRightCount);
|
||||
} else {
|
||||
|
@ -3511,35 +3538,40 @@ void DecimalFormat::setMinimumFractionDigits(int32_t newValue) {
|
|||
}
|
||||
|
||||
int32_t DecimalFormat::getMinimumSignificantDigits() const {
|
||||
return -getMinimumIntegerDigits();
|
||||
return fMinSignificantDigits;
|
||||
}
|
||||
|
||||
int32_t DecimalFormat::getMaximumSignificantDigits() const {
|
||||
return -getMaximumIntegerDigits();
|
||||
return fMaxSignificantDigits;
|
||||
}
|
||||
|
||||
void DecimalFormat::setMinimumSignificantDigits(int32_t min) {
|
||||
if (min < 1) {
|
||||
min = 1;
|
||||
}
|
||||
// pin max sig dig to >= min; if unset, use min
|
||||
int32_t max = _max(getMaximumSignificantDigits(), min);
|
||||
internalSetMinimumIntegerDigits(-min);
|
||||
internalSetMaximumIntegerDigits(-max);
|
||||
// pin max sig dig to >= min
|
||||
int32_t max = _max(fMaxSignificantDigits, min);
|
||||
fMinSignificantDigits = min;
|
||||
fMaxSignificantDigits = max;
|
||||
}
|
||||
|
||||
void DecimalFormat::setMaximumSignificantDigits(int32_t max) {
|
||||
if (max < 1) {
|
||||
max = 1;
|
||||
}
|
||||
// pin min sig dig to 1..max; if unset, use 1
|
||||
int32_t min = _min(_max(getMinimumSignificantDigits(), 1), max);
|
||||
internalSetMinimumIntegerDigits(-min);
|
||||
internalSetMaximumIntegerDigits(-max);
|
||||
// pin min sig dig to 1..max
|
||||
U_ASSERT(fMinSignificantDigits >= 1);
|
||||
int32_t min = _min(fMinSignificantDigits, max);
|
||||
fMinSignificantDigits = min;
|
||||
fMaxSignificantDigits = max;
|
||||
}
|
||||
|
||||
UBool DecimalFormat::useSignificantDigits() const {
|
||||
return getMinimumIntegerDigits() < 0;
|
||||
UBool DecimalFormat::isSignificantDigits() const {
|
||||
return fUseSignificantDigits;
|
||||
}
|
||||
|
||||
void DecimalFormat::setSignificantDigits(UBool useSignificantDigits) {
|
||||
fUseSignificantDigits = useSignificantDigits;
|
||||
}
|
||||
|
||||
void DecimalFormat::setCurrency(const UChar* theCurrency, UErrorCode& ec) {
|
||||
|
@ -3582,7 +3614,7 @@ void DecimalFormat::setCurrency(const UChar* theCurrency, UErrorCode& ec) {
|
|||
*/
|
||||
int32_t
|
||||
DecimalFormat::precision(UBool isIntegral) const {
|
||||
if (useSignificantDigits()) {
|
||||
if (isSignificantDigits()) {
|
||||
return getMaximumSignificantDigits();
|
||||
} else if (fUseExponentialNotation) {
|
||||
return getMinimumIntegerDigits() + getMaximumFractionDigits();
|
||||
|
|
|
@ -430,13 +430,11 @@ class ChoiceFormat;
|
|||
* <ul>
|
||||
* <li>In order to enable significant digits formatting, use a pattern
|
||||
* containing the <code>'@'</code> pattern character. Alternatively,
|
||||
* call either setMinimumSignificantDigits() or
|
||||
* setMaximumSignificantDigits().
|
||||
* call setSignificantDigits(TRUE).
|
||||
*
|
||||
* <li>In order to disable significant digits formatting, use a
|
||||
* pattern containing the <code>'0'</code> pattern
|
||||
* character. Alternatively, call either
|
||||
* setMinimumIntegerDigits() or setMaximumIntegerDigits().
|
||||
* character. Alternatively, call setSignificantDigits(FALSE).
|
||||
*
|
||||
* <li>If a pattern uses significant digits, it may not contain
|
||||
* the <code>'0'</code> character, nor may it include a fraction
|
||||
|
@ -469,16 +467,8 @@ class ChoiceFormat;
|
|||
* count of getMaximumSignificantDigits()<code> - 1</code>. For example, the
|
||||
* pattern <code>\htmlonly"@@###E0"\endhtmlonly</code> is equivalent to <code>\htmlonly"0.0###E0"\endhtmlonly</code>.
|
||||
*
|
||||
* <li>Significant digit counts are stored as negative values in the
|
||||
* integer digit count fields. Thus, if significant digits are used,
|
||||
* then getMinimumIntegerDigits() and
|
||||
* getMaximumIntegerDigits() will return negative numbers. The
|
||||
* converse is also true. If significant digits are not being used,
|
||||
* then getMinimumSignificantDigits() and
|
||||
* getMaximumSignificantDigits() will return non-positive numbers.
|
||||
*
|
||||
* <li>If significant digits are in use, then the fraction digit counts
|
||||
* are ignored.
|
||||
* <li>If significant digits are in use, then the integer and fraction
|
||||
* digit counts are ignored.
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
|
@ -1471,18 +1461,18 @@ public:
|
|||
|
||||
/**
|
||||
* Returns the minimum number of significant digits that will be
|
||||
* displayed.
|
||||
* @return the fewest significant digits that will be shown, or a
|
||||
* non-positive value if significant digits are not in use
|
||||
* displayed. This value has no effect unless isSignficantDigits()
|
||||
* returns true.
|
||||
* @return the fewest significant digits that will be shown
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
int32_t getMinimumSignificantDigits() const;
|
||||
|
||||
/**
|
||||
* Returns the maximum number of significant digits that will be
|
||||
* displayed.
|
||||
* @return the most significant digits that will be shown, or a
|
||||
* non-positive value if significant digits are not in use
|
||||
* displayed. This value has no effect unless isSignficantDigits()
|
||||
* returns true.
|
||||
* @return the most significant digits that will be shown
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
int32_t getMaximumSignificantDigits() const;
|
||||
|
@ -1491,10 +1481,8 @@ public:
|
|||
* Sets the minimum number of significant digits that will be
|
||||
* displayed. If <code>min</code> is less than one then it is set
|
||||
* to one. If the maximum significant digits count is less than
|
||||
* <code>min</code>, then it is set to <code>min</code>. If
|
||||
* significant digits were not in use before this call, then the
|
||||
* maximum significant digits count will be set to
|
||||
* <code>min</code>.
|
||||
* <code>min</code>, then it is set to <code>min</code>. This
|
||||
* value has no effect unless isSignficantDigits() returns true.
|
||||
* @param min the fewest significant digits to be shown
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
|
@ -1504,19 +1492,30 @@ public:
|
|||
* Sets the maximum number of significant digits that will be
|
||||
* displayed. If <code>max</code> is less than one then it is set
|
||||
* to one. If the minimum significant digits count is greater
|
||||
* than <code>max</code>, then it is set to <code>max</code>. If
|
||||
* significant digits were not in use before this call, then the
|
||||
* minimum significant digits count will be set to one.
|
||||
* than <code>max</code>, then it is set to <code>max</code>.
|
||||
* This value has no effect unless isSignficantDigits() returns
|
||||
* true.
|
||||
* @param max the most significant digits to be shown
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
void setMaximumSignificantDigits(int32_t max);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Returns true if significant digits are in use.
|
||||
* Returns true if significant digits are in use, or false if
|
||||
* integer and fraction digit counts are in use.
|
||||
* @return true if significant digits are in use
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
UBool useSignificantDigits() const;
|
||||
UBool isSignificantDigits() const;
|
||||
|
||||
/**
|
||||
* Sets whether significant digits are in use, or integer and
|
||||
* fraction digit counts are in use.
|
||||
* @param useSignficantDigits true to use significant digits, or
|
||||
* false to use integer and fraction digit counts
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
void setSignificantDigits(UBool useSignificantDigits);
|
||||
|
||||
public:
|
||||
/**
|
||||
|
@ -1732,13 +1731,17 @@ private:
|
|||
int32_t fMultiplier;
|
||||
int32_t fGroupingSize;
|
||||
int32_t fGroupingSize2;
|
||||
UBool fDecimalSeparatorAlwaysShown;
|
||||
/*transient*/ UBool fIsCurrencyFormat;
|
||||
UBool fDecimalSeparatorAlwaysShown;
|
||||
/*transient*/ UBool fIsCurrencyFormat;
|
||||
DecimalFormatSymbols* fSymbols;
|
||||
|
||||
UBool fUseExponentialNotation;
|
||||
UBool fUseSignificantDigits;
|
||||
int32_t fMinSignificantDigits;
|
||||
int32_t fMaxSignificantDigits;
|
||||
|
||||
UBool fUseExponentialNotation;
|
||||
int8_t fMinExponentDigits;
|
||||
UBool fExponentSignAlwaysShown;
|
||||
UBool fExponentSignAlwaysShown;
|
||||
|
||||
/* If fRoundingIncrement is NULL, there is no rounding. Otherwise, round to
|
||||
* fRoundingIncrement.getDouble(). Since this operation may be expensive,
|
||||
|
|
Loading…
Add table
Reference in a new issue