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