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