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 org.apache.commons.math.ConvergenceException;
20
21 import junit.framework.TestCase;
22
23
24
25
26 public class FractionTest extends TestCase {
27
28 private void assertFraction(int expectedNumerator, int expectedDenominator, Fraction actual) {
29 assertEquals(expectedNumerator, actual.getNumerator());
30 assertEquals(expectedDenominator, actual.getDenominator());
31 }
32
33 public void testConstructor() {
34 assertFraction(0, 1, new Fraction(0, 1));
35 assertFraction(0, 1, new Fraction(0, 2));
36 assertFraction(0, 1, new Fraction(0, -1));
37 assertFraction(1, 2, new Fraction(1, 2));
38 assertFraction(1, 2, new Fraction(2, 4));
39 assertFraction(-1, 2, new Fraction(-1, 2));
40 assertFraction(-1, 2, new Fraction(1, -2));
41 assertFraction(-1, 2, new Fraction(-2, 4));
42 assertFraction(-1, 2, new Fraction(2, -4));
43
44
45 try {
46 new Fraction(Integer.MIN_VALUE, -1);
47 fail();
48 } catch (ArithmeticException ex) {
49
50 }
51 try {
52 new Fraction(1, Integer.MIN_VALUE);
53 fail();
54 } catch (ArithmeticException ex) {
55
56 }
57 try {
58 assertFraction(0, 1, new Fraction(0.00000000000001));
59 assertFraction(2, 5, new Fraction(0.40000000000001));
60 assertFraction(15, 1, new Fraction(15.0000000000001));
61
62 } catch (ConvergenceException ex) {
63 fail(ex.getMessage());
64 }
65 }
66
67 public void testGoldenRatio() {
68 try {
69
70 new Fraction((1 + Math.sqrt(5)) / 2, 1.0e-12, 25);
71 fail("an exception should have been thrown");
72 } catch (ConvergenceException ce) {
73
74 } catch (Exception e) {
75 fail("wrong exception caught");
76 }
77 }
78
79
80 public void testDoubleConstructor() throws ConvergenceException {
81 assertFraction(1, 2, new Fraction((double)1 / (double)2));
82 assertFraction(1, 3, new Fraction((double)1 / (double)3));
83 assertFraction(2, 3, new Fraction((double)2 / (double)3));
84 assertFraction(1, 4, new Fraction((double)1 / (double)4));
85 assertFraction(3, 4, new Fraction((double)3 / (double)4));
86 assertFraction(1, 5, new Fraction((double)1 / (double)5));
87 assertFraction(2, 5, new Fraction((double)2 / (double)5));
88 assertFraction(3, 5, new Fraction((double)3 / (double)5));
89 assertFraction(4, 5, new Fraction((double)4 / (double)5));
90 assertFraction(1, 6, new Fraction((double)1 / (double)6));
91 assertFraction(5, 6, new Fraction((double)5 / (double)6));
92 assertFraction(1, 7, new Fraction((double)1 / (double)7));
93 assertFraction(2, 7, new Fraction((double)2 / (double)7));
94 assertFraction(3, 7, new Fraction((double)3 / (double)7));
95 assertFraction(4, 7, new Fraction((double)4 / (double)7));
96 assertFraction(5, 7, new Fraction((double)5 / (double)7));
97 assertFraction(6, 7, new Fraction((double)6 / (double)7));
98 assertFraction(1, 8, new Fraction((double)1 / (double)8));
99 assertFraction(3, 8, new Fraction((double)3 / (double)8));
100 assertFraction(5, 8, new Fraction((double)5 / (double)8));
101 assertFraction(7, 8, new Fraction((double)7 / (double)8));
102 assertFraction(1, 9, new Fraction((double)1 / (double)9));
103 assertFraction(2, 9, new Fraction((double)2 / (double)9));
104 assertFraction(4, 9, new Fraction((double)4 / (double)9));
105 assertFraction(5, 9, new Fraction((double)5 / (double)9));
106 assertFraction(7, 9, new Fraction((double)7 / (double)9));
107 assertFraction(8, 9, new Fraction((double)8 / (double)9));
108 assertFraction(1, 10, new Fraction((double)1 / (double)10));
109 assertFraction(3, 10, new Fraction((double)3 / (double)10));
110 assertFraction(7, 10, new Fraction((double)7 / (double)10));
111 assertFraction(9, 10, new Fraction((double)9 / (double)10));
112 assertFraction(1, 11, new Fraction((double)1 / (double)11));
113 assertFraction(2, 11, new Fraction((double)2 / (double)11));
114 assertFraction(3, 11, new Fraction((double)3 / (double)11));
115 assertFraction(4, 11, new Fraction((double)4 / (double)11));
116 assertFraction(5, 11, new Fraction((double)5 / (double)11));
117 assertFraction(6, 11, new Fraction((double)6 / (double)11));
118 assertFraction(7, 11, new Fraction((double)7 / (double)11));
119 assertFraction(8, 11, new Fraction((double)8 / (double)11));
120 assertFraction(9, 11, new Fraction((double)9 / (double)11));
121 assertFraction(10, 11, new Fraction((double)10 / (double)11));
122 }
123
124
125 public void testDigitLimitConstructor() throws ConvergenceException {
126 assertFraction(2, 5, new Fraction(0.4, 9));
127 assertFraction(2, 5, new Fraction(0.4, 99));
128 assertFraction(2, 5, new Fraction(0.4, 999));
129
130 assertFraction(3, 5, new Fraction(0.6152, 9));
131 assertFraction(8, 13, new Fraction(0.6152, 99));
132 assertFraction(510, 829, new Fraction(0.6152, 999));
133 assertFraction(769, 1250, new Fraction(0.6152, 9999));
134 }
135
136 public void testIntegerOverflow() {
137 checkIntegerOverflow(0.75000000001455192);
138 checkIntegerOverflow(1.0e10);
139 }
140
141 private void checkIntegerOverflow(double a) {
142 try {
143 new Fraction(a, 1.0e-12, 1000);
144 fail("an exception should have been thrown");
145 } catch (ConvergenceException ce) {
146
147 } catch (Exception e) {
148 fail("wrong exception caught");
149 }
150 }
151
152 public void testEpsilonLimitConstructor() throws ConvergenceException {
153 assertFraction(2, 5, new Fraction(0.4, 1.0e-5, 100));
154
155 assertFraction(3, 5, new Fraction(0.6152, 0.02, 100));
156 assertFraction(8, 13, new Fraction(0.6152, 1.0e-3, 100));
157 assertFraction(251, 408, new Fraction(0.6152, 1.0e-4, 100));
158 assertFraction(251, 408, new Fraction(0.6152, 1.0e-5, 100));
159 assertFraction(510, 829, new Fraction(0.6152, 1.0e-6, 100));
160 assertFraction(769, 1250, new Fraction(0.6152, 1.0e-7, 100));
161 }
162
163 public void testCompareTo() {
164 Fraction first = new Fraction(1, 2);
165 Fraction second = new Fraction(1, 3);
166 Fraction third = new Fraction(1, 2);
167
168 assertEquals(0, first.compareTo(first));
169 assertEquals(0, first.compareTo(third));
170 assertEquals(1, first.compareTo(second));
171 assertEquals(-1, second.compareTo(first));
172 }
173
174 public void testDoubleValue() {
175 Fraction first = new Fraction(1, 2);
176 Fraction second = new Fraction(1, 3);
177
178 assertEquals(0.5, first.doubleValue(), 0.0);
179 assertEquals(1.0 / 3.0, second.doubleValue(), 0.0);
180 }
181
182 public void testFloatValue() {
183 Fraction first = new Fraction(1, 2);
184 Fraction second = new Fraction(1, 3);
185
186 assertEquals(0.5f, first.floatValue(), 0.0f);
187 assertEquals((float)(1.0 / 3.0), second.floatValue(), 0.0f);
188 }
189
190 public void testIntValue() {
191 Fraction first = new Fraction(1, 2);
192 Fraction second = new Fraction(3, 2);
193
194 assertEquals(0, first.intValue());
195 assertEquals(1, second.intValue());
196 }
197
198 public void testLongValue() {
199 Fraction first = new Fraction(1, 2);
200 Fraction second = new Fraction(3, 2);
201
202 assertEquals(0L, first.longValue());
203 assertEquals(1L, second.longValue());
204 }
205
206 public void testConstructorDouble() {
207 try {
208 assertFraction(1, 2, new Fraction(0.5));
209 assertFraction(1, 3, new Fraction(1.0 / 3.0));
210 assertFraction(17, 100, new Fraction(17.0 / 100.0));
211 assertFraction(317, 100, new Fraction(317.0 / 100.0));
212 assertFraction(-1, 2, new Fraction(-0.5));
213 assertFraction(-1, 3, new Fraction(-1.0 / 3.0));
214 assertFraction(-17, 100, new Fraction(17.0 / -100.0));
215 assertFraction(-317, 100, new Fraction(-317.0 / 100.0));
216 } catch (ConvergenceException ex) {
217 fail(ex.getMessage());
218 }
219 }
220
221 public void testAbs() {
222 Fraction a = new Fraction(10, 21);
223 Fraction b = new Fraction(-10, 21);
224 Fraction c = new Fraction(10, -21);
225
226 assertFraction(10, 21, a.abs());
227 assertFraction(10, 21, b.abs());
228 assertFraction(10, 21, c.abs());
229 }
230
231 public void testReciprocal() {
232 Fraction f = null;
233
234 f = new Fraction(50, 75);
235 f = f.reciprocal();
236 assertEquals(3, f.getNumerator());
237 assertEquals(2, f.getDenominator());
238
239 f = new Fraction(4, 3);
240 f = f.reciprocal();
241 assertEquals(3, f.getNumerator());
242 assertEquals(4, f.getDenominator());
243
244 f = new Fraction(-15, 47);
245 f = f.reciprocal();
246 assertEquals(-47, f.getNumerator());
247 assertEquals(15, f.getDenominator());
248
249 f = new Fraction(0, 3);
250 try {
251 f = f.reciprocal();
252 fail("expecting ArithmeticException");
253 } catch (ArithmeticException ex) {}
254
255
256 f = new Fraction(Integer.MAX_VALUE, 1);
257 f = f.reciprocal();
258 assertEquals(1, f.getNumerator());
259 assertEquals(Integer.MAX_VALUE, f.getDenominator());
260 }
261
262 public void testNegate() {
263 Fraction f = null;
264
265 f = new Fraction(50, 75);
266 f = f.negate();
267 assertEquals(-2, f.getNumerator());
268 assertEquals(3, f.getDenominator());
269
270 f = new Fraction(-50, 75);
271 f = f.negate();
272 assertEquals(2, f.getNumerator());
273 assertEquals(3, f.getDenominator());
274
275
276 f = new Fraction(Integer.MAX_VALUE-1, Integer.MAX_VALUE);
277 f = f.negate();
278 assertEquals(Integer.MIN_VALUE+2, f.getNumerator());
279 assertEquals(Integer.MAX_VALUE, f.getDenominator());
280
281 f = new Fraction(Integer.MIN_VALUE, 1);
282 try {
283 f = f.negate();
284 fail("expecting ArithmeticException");
285 } catch (ArithmeticException ex) {}
286 }
287
288 public void testAdd() {
289 Fraction a = new Fraction(1, 2);
290 Fraction b = new Fraction(2, 3);
291
292 assertFraction(1, 1, a.add(a));
293 assertFraction(7, 6, a.add(b));
294 assertFraction(7, 6, b.add(a));
295 assertFraction(4, 3, b.add(b));
296
297 Fraction f1 = new Fraction(Integer.MAX_VALUE - 1, 1);
298 Fraction f2 = Fraction.ONE;
299 Fraction f = f1.add(f2);
300 assertEquals(Integer.MAX_VALUE, f.getNumerator());
301 assertEquals(1, f.getDenominator());
302
303 f1 = new Fraction(-1, 13*13*2*2);
304 f2 = new Fraction(-2, 13*17*2);
305 f = f1.add(f2);
306 assertEquals(13*13*17*2*2, f.getDenominator());
307 assertEquals(-17 - 2*13*2, f.getNumerator());
308
309 try {
310 f.add(null);
311 fail("expecting IllegalArgumentException");
312 } catch (IllegalArgumentException ex) {}
313
314
315
316 f1 = new Fraction(1,32768*3);
317 f2 = new Fraction(1,59049);
318 f = f1.add(f2);
319 assertEquals(52451, f.getNumerator());
320 assertEquals(1934917632, f.getDenominator());
321
322 f1 = new Fraction(Integer.MIN_VALUE, 3);
323 f2 = new Fraction(1,3);
324 f = f1.add(f2);
325 assertEquals(Integer.MIN_VALUE+1, f.getNumerator());
326 assertEquals(3, f.getDenominator());
327
328 f1 = new Fraction(Integer.MAX_VALUE - 1, 1);
329 f2 = Fraction.ONE;
330 f = f1.add(f2);
331 assertEquals(Integer.MAX_VALUE, f.getNumerator());
332 assertEquals(1, f.getDenominator());
333
334 try {
335 f = f.add(Fraction.ONE);
336 fail("expecting ArithmeticException but got: " + f.toString());
337 } catch (ArithmeticException ex) {}
338
339
340 f1 = new Fraction(Integer.MIN_VALUE, 5);
341 f2 = new Fraction(-1,5);
342 try {
343 f = f1.add(f2);
344 fail("expecting ArithmeticException but got: " + f.toString());
345 } catch (ArithmeticException ex) {}
346
347 try {
348 f= new Fraction(-Integer.MAX_VALUE, 1);
349 f = f.add(f);
350 fail("expecting ArithmeticException");
351 } catch (ArithmeticException ex) {}
352
353 try {
354 f= new Fraction(-Integer.MAX_VALUE, 1);
355 f = f.add(f);
356 fail("expecting ArithmeticException");
357 } catch (ArithmeticException ex) {}
358
359 f1 = new Fraction(3,327680);
360 f2 = new Fraction(2,59049);
361 try {
362 f = f1.add(f2);
363 fail("expecting ArithmeticException but got: " + f.toString());
364 } catch (ArithmeticException ex) {}
365 }
366
367 public void testDivide() {
368 Fraction a = new Fraction(1, 2);
369 Fraction b = new Fraction(2, 3);
370
371 assertFraction(1, 1, a.divide(a));
372 assertFraction(3, 4, a.divide(b));
373 assertFraction(4, 3, b.divide(a));
374 assertFraction(1, 1, b.divide(b));
375
376 Fraction f1 = new Fraction(3, 5);
377 Fraction f2 = Fraction.ZERO;
378 try {
379 f1.divide(f2);
380 fail("expecting ArithmeticException");
381 } catch (ArithmeticException ex) {}
382
383 f1 = new Fraction(0, 5);
384 f2 = new Fraction(2, 7);
385 Fraction f = f1.divide(f2);
386 assertSame(Fraction.ZERO, f);
387
388 f1 = new Fraction(2, 7);
389 f2 = Fraction.ONE;
390 f = f1.divide(f2);
391 assertEquals(2, f.getNumerator());
392 assertEquals(7, f.getDenominator());
393
394 f1 = new Fraction(1, Integer.MAX_VALUE);
395 f = f1.divide(f1);
396 assertEquals(1, f.getNumerator());
397 assertEquals(1, f.getDenominator());
398
399 f1 = new Fraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
400 f2 = new Fraction(1, Integer.MAX_VALUE);
401 f = f1.divide(f2);
402 assertEquals(Integer.MIN_VALUE, f.getNumerator());
403 assertEquals(1, f.getDenominator());
404
405 try {
406 f.divide(null);
407 fail("IllegalArgumentException");
408 } catch (IllegalArgumentException ex) {}
409
410 try {
411 f1 = new Fraction(1, Integer.MAX_VALUE);
412 f = f1.divide(f1.reciprocal());
413 fail("expecting ArithmeticException");
414 } catch (ArithmeticException ex) {}
415 try {
416 f1 = new Fraction(1, -Integer.MAX_VALUE);
417 f = f1.divide(f1.reciprocal());
418 fail("expecting ArithmeticException");
419 } catch (ArithmeticException ex) {}
420 }
421
422 public void testMultiply() {
423 Fraction a = new Fraction(1, 2);
424 Fraction b = new Fraction(2, 3);
425
426 assertFraction(1, 4, a.multiply(a));
427 assertFraction(1, 3, a.multiply(b));
428 assertFraction(1, 3, b.multiply(a));
429 assertFraction(4, 9, b.multiply(b));
430
431 Fraction f1 = new Fraction(Integer.MAX_VALUE, 1);
432 Fraction f2 = new Fraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
433 Fraction f = f1.multiply(f2);
434 assertEquals(Integer.MIN_VALUE, f.getNumerator());
435 assertEquals(1, f.getDenominator());
436
437 try {
438 f.multiply(null);
439 fail("expecting IllegalArgumentException");
440 } catch (IllegalArgumentException ex) {}
441 }
442
443 public void testSubtract() {
444 Fraction a = new Fraction(1, 2);
445 Fraction b = new Fraction(2, 3);
446
447 assertFraction(0, 1, a.subtract(a));
448 assertFraction(-1, 6, a.subtract(b));
449 assertFraction(1, 6, b.subtract(a));
450 assertFraction(0, 1, b.subtract(b));
451
452 Fraction f = new Fraction(1,1);
453 try {
454 f.subtract(null);
455 fail("expecting IllegalArgumentException");
456 } catch (IllegalArgumentException ex) {}
457
458
459
460 Fraction f1 = new Fraction(1,32768*3);
461 Fraction f2 = new Fraction(1,59049);
462 f = f1.subtract(f2);
463 assertEquals(-13085, f.getNumerator());
464 assertEquals(1934917632, f.getDenominator());
465
466 f1 = new Fraction(Integer.MIN_VALUE, 3);
467 f2 = new Fraction(1,3).negate();
468 f = f1.subtract(f2);
469 assertEquals(Integer.MIN_VALUE+1, f.getNumerator());
470 assertEquals(3, f.getDenominator());
471
472 f1 = new Fraction(Integer.MAX_VALUE, 1);
473 f2 = Fraction.ONE;
474 f = f1.subtract(f2);
475 assertEquals(Integer.MAX_VALUE-1, f.getNumerator());
476 assertEquals(1, f.getDenominator());
477
478 try {
479 f1 = new Fraction(1, Integer.MAX_VALUE);
480 f2 = new Fraction(1, Integer.MAX_VALUE - 1);
481 f = f1.subtract(f2);
482 fail("expecting ArithmeticException");
483 } catch (ArithmeticException ex) {}
484
485
486 f1 = new Fraction(Integer.MIN_VALUE, 5);
487 f2 = new Fraction(1,5);
488 try {
489 f = f1.subtract(f2);
490 fail("expecting ArithmeticException but got: " + f.toString());
491 } catch (ArithmeticException ex) {}
492
493 try {
494 f= new Fraction(Integer.MIN_VALUE, 1);
495 f = f.subtract(Fraction.ONE);
496 fail("expecting ArithmeticException");
497 } catch (ArithmeticException ex) {}
498
499 try {
500 f= new Fraction(Integer.MAX_VALUE, 1);
501 f = f.subtract(Fraction.ONE.negate());
502 fail("expecting ArithmeticException");
503 } catch (ArithmeticException ex) {}
504
505 f1 = new Fraction(3,327680);
506 f2 = new Fraction(2,59049);
507 try {
508 f = f1.subtract(f2);
509 fail("expecting ArithmeticException but got: " + f.toString());
510 } catch (ArithmeticException ex) {}
511 }
512
513 public void testEqualsAndHashCode() {
514 Fraction zero = new Fraction(0,1);
515 Fraction nullFraction = null;
516 assertTrue( zero.equals(zero));
517 assertFalse(zero.equals(nullFraction));
518 assertFalse(zero.equals(new Double(0)));
519 Fraction zero2 = new Fraction(0,2);
520 assertTrue(zero.equals(zero2));
521 assertEquals(zero.hashCode(), zero2.hashCode());
522 Fraction one = new Fraction(1,1);
523 assertFalse((one.equals(zero) ||zero.equals(one)));
524 }
525
526 public void testGetReducedFraction() {
527 Fraction threeFourths = new Fraction(3, 4);
528 assertTrue(threeFourths.equals(Fraction.getReducedFraction(6, 8)));
529 assertTrue(Fraction.ZERO.equals(Fraction.getReducedFraction(0, -1)));
530 try {
531 Fraction.getReducedFraction(1, 0);
532 fail("expecting ArithmeticException");
533 } catch (ArithmeticException ex) {
534
535 }
536 assertEquals(Fraction.getReducedFraction
537 (2, Integer.MIN_VALUE).getNumerator(),-1);
538 assertEquals(Fraction.getReducedFraction
539 (1, -1).getNumerator(), -1);
540 }
541 }