001: package gnu.text;
002:
003: import java.text.FieldPosition;
004: import gnu.lists.*;
005:
006: public class EnglishIntegerFormat extends java.text.NumberFormat
007: // or extends AbstractFormat?
008: {
009: private static EnglishIntegerFormat cardinalEnglish;
010: private static EnglishIntegerFormat ordinalEnglish;
011:
012: public boolean ordinal;
013:
014: public EnglishIntegerFormat(boolean ordinal) {
015: this .ordinal = ordinal;
016: }
017:
018: public static EnglishIntegerFormat getInstance(boolean ordinal) {
019: if (ordinal) {
020: if (ordinalEnglish == null)
021: ordinalEnglish = new EnglishIntegerFormat(true);
022: return ordinalEnglish;
023: } else {
024: if (cardinalEnglish == null)
025: cardinalEnglish = new EnglishIntegerFormat(false);
026: return cardinalEnglish;
027: }
028: }
029:
030: public static final String[] ones = { null, "one", "two", "three",
031: "four", "five", "six", "seven", "eight", "nine", "ten",
032: "eleven", "twelve", "thirteen", "fourteen", "fifteen",
033: "sixteen", "seventeen", "eighteen", "nineteen" };
034:
035: public static final String[] onesth = { null, "first", "second",
036: "third", "fourth", "fifth", "sixth", "seventh", "eighth",
037: "ninth", "tenth", "eleventh", "twelveth", "thirteenth",
038: "fourteenth", "fifteenth", "sixteenth", "seventeenth",
039: "eighteenth", "nineteenth" };
040:
041: public static final String[] tens = { null, null, "twenty",
042: "thirty", "forty", "fifty", "sixty", "seventy", "eighty",
043: "ninety" };
044:
045: public static final String[] tensth = { null, null, "twentieth",
046: "thirtieth", "fortieth", "fiftieth", "sixtieth",
047: "seventieth", "eightieth", "ninetieth" };
048:
049: public static final String[] power1000s = { null, " thousand",
050: " million", " billion", " trillion", " quadrillion",
051: " quintillion", " sextillion", " septillion", " octillion",
052: " nonillion", " decillion", " undecillion",
053: " duodecillion", " tredecillion", " quattuordecillion",
054: " quindecillion", " sexdecillion", " septendecillion",
055: " octodecillion", " novemdecillion", " vigintillion" };
056:
057: // Inspired by the Slib version, which is inspired
058: // by Bruno Haible's CLisp function format-small-cardinal.
059:
060: /** Convert numbers in the range 1 to 998. */
061: void format999(StringBuffer sbuf, int num, boolean ordinal) {
062: if (num >= 100) {
063: int num100s = num / 100;
064: num = num % 100;
065: if (num100s > 1) {
066: sbuf.append(ones[num100s]);
067: sbuf.append(' ');
068: }
069: sbuf.append("hundred");
070: if (num > 0)
071: sbuf.append(' ');
072: else if (ordinal)
073: sbuf.append("th");
074: }
075: if (num >= 20) {
076: int num10s = num / 10;
077: num = num % 10;
078: sbuf.append((ordinal && num == 0 ? tensth : tens)[num10s]);
079: if (num > 0)
080: sbuf.append('-');
081: }
082: if (num > 0) {
083: sbuf.append((ordinal ? onesth : ones)[num]);
084: }
085: }
086:
087: void format(StringBuffer sbuf, long num, int exp1000,
088: boolean ordinal) {
089: if (num >= 1000) {
090: format(sbuf, num / 1000, exp1000 + 1, false);
091: num = num % 1000;
092: if (num > 0)
093: sbuf.append(", ");
094: else if (ordinal)
095: sbuf.append("th");
096: }
097: if (num > 0) {
098: format999(sbuf, (int) num, ordinal && exp1000 == 0);
099: if (exp1000 >= power1000s.length) {
100: sbuf.append(" times ten to the ");
101: format(sbuf, exp1000 * 3, 0, true);
102: sbuf.append(" power");
103: } else if (exp1000 > 0)
104: sbuf.append(power1000s[exp1000]);
105: }
106: }
107:
108: public void writeInt(int value, Consumer out) {
109: writeLong(value, out);
110: }
111:
112: public void writeLong(long value, Consumer out) {
113: StringBuffer sbuf = new StringBuffer();
114: format(value, sbuf, null);
115: /* #ifdef use:java.lang.CharSequence */
116: out.write(sbuf, 0, sbuf.length());
117: /* #else */
118: // out.write(sbuf.toString());
119: /* #endif */
120: }
121:
122: public void writeObject(Object value, Consumer out) {
123: writeLong(((Number) value).longValue(), out);
124: }
125:
126: public void writeBoolean(boolean value, Consumer out) {
127: writeLong(value ? 1 : 0, out);
128: }
129:
130: public StringBuffer format(long num, StringBuffer sbuf,
131: FieldPosition fpos) {
132: if (num == 0)
133: sbuf.append(ordinal ? "zeroth" : "zero");
134: else {
135: if (num < 0) {
136: sbuf.append("minus ");
137: num = -num; // What about -2**31?
138: }
139: format(sbuf, num, 0, ordinal);
140: }
141: if (fpos != null) {
142: // FIXME [using JDK 1.2]
143: }
144: return sbuf;
145: }
146:
147: public StringBuffer format(double num, StringBuffer sbuf,
148: FieldPosition fpos) {
149: long inum = (long) num;
150: if ((double) inum == num)
151: return format(inum, sbuf, fpos);
152: sbuf.append(Double.toString(num));
153: return sbuf;
154: }
155:
156: public java.lang.Number parse(String text,
157: java.text.ParsePosition status) {
158: throw new Error(
159: "EnglishIntegerFormat.parseObject - not implemented");
160: }
161: }
|