1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.math.fraction;
17
18 import java.text.FieldPosition;
19 import java.text.NumberFormat;
20 import java.text.ParsePosition;
21
22 import org.apache.commons.math.util.MathUtils;
23
24
25
26
27
28
29
30
31 public class ProperFractionFormat extends FractionFormat {
32
33
34 private static final long serialVersionUID = -6337346779577272307L;
35
36
37 private NumberFormat wholeFormat;
38
39
40
41
42
43 public ProperFractionFormat() {
44 this(getDefaultNumberFormat());
45 }
46
47
48
49
50
51
52
53 public ProperFractionFormat(NumberFormat format) {
54 this(format, (NumberFormat)format.clone(), (NumberFormat)format.clone());
55 }
56
57
58
59
60
61
62
63
64 public ProperFractionFormat(NumberFormat wholeFormat,
65 NumberFormat numeratorFormat,
66 NumberFormat denominatorFormat)
67 {
68 super(numeratorFormat, denominatorFormat);
69 setWholeFormat(wholeFormat);
70 }
71
72
73
74
75
76
77
78
79
80
81
82 public StringBuffer format(Fraction fraction, StringBuffer toAppendTo,
83 FieldPosition pos) {
84
85 pos.setBeginIndex(0);
86 pos.setEndIndex(0);
87
88 int num = fraction.getNumerator();
89 int den = fraction.getDenominator();
90 int whole = num / den;
91 num = num % den;
92
93 if (whole != 0) {
94 getWholeFormat().format(whole, toAppendTo, pos);
95 toAppendTo.append(' ');
96 num = Math.abs(num);
97 }
98 getNumeratorFormat().format(num, toAppendTo, pos);
99 toAppendTo.append(" / ");
100 getDenominatorFormat().format(den, toAppendTo,
101 pos);
102
103 return toAppendTo;
104 }
105
106
107
108
109
110 public NumberFormat getWholeFormat() {
111 return wholeFormat;
112 }
113
114
115
116
117
118
119
120
121 public Fraction parse(String source, ParsePosition pos) {
122
123 Fraction ret = super.parse(source, pos);
124 if (ret != null) {
125 return ret;
126 }
127
128 int initialIndex = pos.getIndex();
129
130
131 parseAndIgnoreWhitespace(source, pos);
132
133
134 Number whole = getWholeFormat().parse(source, pos);
135 if (whole == null) {
136
137
138
139 pos.setIndex(initialIndex);
140 return null;
141 }
142
143
144 parseAndIgnoreWhitespace(source, pos);
145
146
147 Number num = getNumeratorFormat().parse(source, pos);
148 if (num == null) {
149
150
151
152 pos.setIndex(initialIndex);
153 return null;
154 }
155
156
157 int startIndex = pos.getIndex();
158 char c = parseNextCharacter(source, pos);
159 switch (c) {
160 case 0 :
161
162
163 return new Fraction(num.intValue(), 1);
164 case '/' :
165
166 break;
167 default :
168
169
170
171 pos.setIndex(initialIndex);
172 pos.setErrorIndex(startIndex);
173 return null;
174 }
175
176
177 parseAndIgnoreWhitespace(source, pos);
178
179
180 Number den = getDenominatorFormat().parse(source, pos);
181 if (den == null) {
182
183
184
185 pos.setIndex(initialIndex);
186 return null;
187 }
188
189 int w = whole.intValue();
190 int n = num.intValue();
191 int d = den.intValue();
192 return new Fraction(((Math.abs(w) * d) + n) * MathUtils.sign(w), d);
193 }
194
195
196
197
198
199
200
201 public void setWholeFormat(NumberFormat format) {
202 if (format == null) {
203 throw new IllegalArgumentException(
204 "whole format can not be null.");
205 }
206 this.wholeFormat = format;
207 }
208 }