• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1---
2layout: default
3title: RuleBasedNumberFormat Examples
4nav_order: 6
5grand_parent: Formatting
6parent: Formatting Numbers
7---
8<!--
9© 2020 and later: Unicode, Inc. and others.
10License & terms of use: http://www.unicode.org/copyright.html
11-->
12
13# `RuleBasedNumberFormat` Examples
14{: .no_toc }
15
16## Contents
17{: .no_toc .text-delta }
18
191. TOC
20{:toc}
21
22---
23
24## Annotated `RuleBasedNumberFormat` Example
25
26The following example provides a quick idea of how the rules work. The
27[`RuleBasedNumberFormat` API
28documentation](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classRuleBasedNumberFormat.html)
29describes the rule syntax in more detail.
30
31This ruleset formats a number using standard decimal place-value notation, but
32using words instead of digits, e.g. 123.4 formats as 'one two three point four':
33
34```
35"-x: minus >>;\n"
36+ "x.x: << point >>;\n"
37+ "zero; one; two; three; four; five; six;\n"
38+ "    seven; eight; nine;\n"
39+ "10: << >>;\n"
40+ "100: << >>>;\n"
41+ "1000: <<, >>>;\n"
42+ "1,000,000: <<, >>>;\n"
43+ "1,000,000,000: <<, >>>;\n"
44+ "1,000,000,000,000: <<, >>>;\n"
45+ "1,000,000,000,000,000: =#,##0=;\n";
46```
47
48In this example, the rules consist of one (unnamed) ruleset. It lists nineteen
49rules, each terminated by a semicolon. It starts with two special rules for
50handling negative numbers and non-integers. (This is true of most rulesets.)
51Following are rules for increasing integer ranges, up to 10e15. The portion of
52the rule before a colon, if any, provides information about the range and some
53additional information about how to apply the rule. Most rule bodies (following
54the colon) consist of recursion instructions and/or plain text substitutions.
55The rules in this example work as follows:
56
571.  **-x: minus >>;**
58    If the number is negative, output the string 'minus ' and recurse using the
59    absolute value.
60
612.  **x.x: << point >>;**
62    If the number is not an integer, recurse using the integral part, emit the
63    string ' point ', and process the ruleset in 'fractional mode' for the
64    fractional part. Generally, this emits single digits.
65
663.  **zero; one; ... nine;**
67    Each of these ten rules applies to a range. By default, the first range
68    starts at zero, and succeeding ranges start at the previous start + 1. These
69    ranges all default, so each of these ten rules has a 'range' of a single
70    integer, 0 to 9. When the current value is in one of these ranges, the rules
71    emit the corresponding text (e.g. 'one', 'two', and so on).
72
734.  **10: << >>;**
74    This starts a new range at 10 (not default) and sets the limit of the range
75    for the previous rule. Divide the number by the divisor (which defaults to
76    the highest power of 10 lower or equal to range start value, e.g. 10),
77    recurse using the integral part, emit the string ' ' (space), then recurse
78    using the remainder.
79
805.  **100: << >>>;**
81    This starts a new range at 100 (again, limiting the previous rule's range).
82    It is similar to the previous rule, except for the use of '>>>'. '>>' means
83    to recurse by matching the value against all the ranges to find the rule,
84    '>>>' means to recurse using the previous rule. We must force the previous
85    rule in order to get the rule for 'ten' invoked in order to emit '0' when
86    processing numbers like 105.
87
886.  **1000: <<, >>>; 1,000,000: ...**
89    These start new ranges at intervals of 1000. They are all similar to the
90    rule for 100 except they output ', ' (comma space) to delimit thousands.
91    Note that the range value can include commas for readability.
92
937.  **1,000... =#,##0=;**
94    This last rule in the ruleset applies to all values at or over 10e15. The
95    pattern '==' means to use the current unmodified value, and text within in
96    the pattern (this works for '<<' and similar patterns as well) describes the
97    ruleset or decimal format to use. If this text starts with '0' or '#', it is
98    presumed to be a decimal format pattern. So this rule means to format the
99    unmodified number using a decimal format constructed with the pattern
100    '#,##0'.
101
102Rulesets are invoked by first applying negative and fractional rules, then by
103finding the rule whose range includes the current value and applying that rule,
104recursing as directed by the rule. Again, a complete description of the rule
105syntax can be found in the [API
106Documentation](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classRuleBasedNumberFormat.html).
107
108More rule examples can be found in the `RuleBasedNumberFormat` [demo
109source](https://github.com/unicode-org/icu/blob/main/icu4j/demos/src/com/ibm/icu/dev/demo/rbnf/RbnfSampleRuleSets.java).
110