Proposal: Significant digits number formatting in ICU 3.0
Alan S Liu <[email protected]> Thu, 25 Mar 2004 13:51:15 -0800
| Newsgroups | gmane.comp.lib.icu.general |
|---|---|
| Message-ID | <OFD7C927C1.46195EA0-ON88256E61.0065440A-88256E62.00780DB8@us.ibm.com> |
Proposal: Significant digits number formatting in ICU 3.0
Affects: ICU4C, ICU4J
Documentation of proposed changes:
DecimalFormat supports significant digits patterns. Rather than
specifying integer and fraction digit counts, these specify a
minimum and maximum number of significant digits. These are
indicated by the '@' and '#' characters. Each formatter object is in
one of two modes, in this regard. Either (a) it uses significant
digits, or (b) it uses the integer and fraction digit counts.
In order to enable significant digits formatting, use a pattern
containing the '@' pattern character. Alternatively, call
setSignificantDigits(true).
In order to disable significant digits formatting, use a pattern
containing the '0' pattern character. Alternatively, call
setSignificantDigits(false).
If a pattern uses significant digits, it may not contain the '0'
character, nor may it include a fraction element. Patterns such as
'@00' or '@.###' are disallowed.
The minimum number of significant digits is the number of '@'
characters. The maximum number of significant digits is the number
of '@' characters plus the number of '#' characters following on the
right. For example, the pattern '@@@' indicates exactly 3
significant digits. The pattern '@##' indicates from 1 to 3
significant digits. Trailing zero digits are suppressed after the
minimum number of significant digits have been shown. This is
similar to the behavior of fraction digits.
Any number of '#' characters may be prepended to the left of the
leftmost '@' character. These have no effect on the minimum and
maximum significant digits counts, but may be used to position
grouping separators. For example, "#,#@#" indicates a minimum of one
significant digits, a maximum of two significant digits, and a
grouping size of three.
The number of significant digits has no effect on parsing.
Significant digits may be used together with exponential
notation. Such patterns are equivalent to a normal exponential
pattern with a minimum and maximum integer digit count of one, a
minimum fraction digit count of getMinimumSignificantDigits() - 1,
and a maximum fraction digit count of getMaximumSignificantDigits()
- 1. For example, the pattern "@@###E0" is equivalent to "0.0###E0".
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.
If significant digits are in use, then the fraction digit counts are
ignored.
Proposed new @draft ICU 3.0 API:
DecimalFormatSymbols (java):
char getSignificantDigit();
void setSignificantDigit(char);
DecimalFormatSymbols (C++):
kSignificantDigitSymbol
unum.h (C):
/* Significant digit symbol */
UNUM_SIGNIFICANT_DIGIT_SYMBOL
/** Minimum significant digits
* @draft ICU 3.0 */
UNUM_MIN_SIGNIFICANT_DIGITS
/** Maximum significant digits
* @draft ICU 3.0 */
UNUM_MAX_SIGNIFICANT_DIGITS
DecimalFormat (C++ and Java):
/**
* 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
* @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
* @draft ICU 3.0
*/
int32_t getMaximumSignificantDigits() const;
/**
* 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>.
* @param min the fewest significant digits to be shown
* @draft ICU 3.0
*/
void setMinimumSignificantDigits(int32_t min);
/**
* 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.
* @param max the most significant digits to be shown
* @draft ICU 3.0
*/
void setMaximumSignificantDigits(int32_t max);
/**
* Returns true if significant digits are in use.
* @draft ICU 3.0
*/
UBool isSignificantDigits() const;
/**
* Sets whether significant digits are in use.
* @draft ICU 3.0
*/
void setSignificantDigits(UBool);
Notes:
An earlier version of this design had no explicit API to set whether
significant digits were in use or not. Instead, this was to be
determined implicitly. If setMinimumSignificantDigits() or
setMaximumSiginificantDigits() was called, then significant digits
mode was turned on. If setMinimumIntegerDigits() or
setMaximumIntegerDigits() was called, then significant digits was
turned off. With this setup, there was no way to tell what mode a
formatter was in. Also, this arrangement would like to code like
this:
fmt.setMinimumSignificantDigits(fmt.getMinimumSignificantDigits());
just to turn significant digits on. It seems better to have an
explicit API.
[Alan S Liu/San Jose/IBM@IBMUS; [email protected];; IBM Globalization;
5600 Cottle Road; San Jose, CA 95193;; (408) 256-3155]