001: /*
002: * Copyright 2005 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.math.fraction;
017:
018: import org.apache.commons.math.ConvergenceException;
019:
020: import junit.framework.TestCase;
021:
022: /**
023: * @version $Revision: 264689 $ $Date: 2005-08-29 20:28:42 -0700 (Mon, 29 Aug 2005) $
024: */
025: public class FractionTest extends TestCase {
026:
027: private void assertFraction(int expectedNumerator,
028: int expectedDenominator, Fraction actual) {
029: assertEquals(expectedNumerator, actual.getNumerator());
030: assertEquals(expectedDenominator, actual.getDenominator());
031: }
032:
033: public void testConstructor() {
034: assertFraction(0, 1, new Fraction(0, 1));
035: assertFraction(0, 1, new Fraction(0, 2));
036: assertFraction(0, 1, new Fraction(0, -1));
037: assertFraction(1, 2, new Fraction(1, 2));
038: assertFraction(1, 2, new Fraction(2, 4));
039: assertFraction(-1, 2, new Fraction(-1, 2));
040: assertFraction(-1, 2, new Fraction(1, -2));
041: assertFraction(-1, 2, new Fraction(-2, 4));
042: assertFraction(-1, 2, new Fraction(2, -4));
043:
044: // overflow
045: try {
046: new Fraction(Integer.MIN_VALUE, -1);
047: fail();
048: } catch (ArithmeticException ex) {
049: // success
050: }
051: try {
052: new Fraction(1, Integer.MIN_VALUE);
053: fail();
054: } catch (ArithmeticException ex) {
055: // success
056: }
057: try {
058: assertFraction(0, 1, new Fraction(0.00000000000001));
059: assertFraction(2, 5, new Fraction(0.40000000000001));
060: assertFraction(15, 1, new Fraction(15.0000000000001));
061:
062: } catch (ConvergenceException ex) {
063: fail(ex.getMessage());
064: }
065: }
066:
067: public void testCompareTo() {
068: Fraction first = new Fraction(1, 2);
069: Fraction second = new Fraction(1, 3);
070: Fraction third = new Fraction(1, 2);
071:
072: assertEquals(0, first.compareTo(first));
073: assertEquals(0, first.compareTo(third));
074: assertEquals(1, first.compareTo(second));
075: assertEquals(-1, second.compareTo(first));
076: }
077:
078: public void testDoubleValue() {
079: Fraction first = new Fraction(1, 2);
080: Fraction second = new Fraction(1, 3);
081:
082: assertEquals(0.5, first.doubleValue(), 0.0);
083: assertEquals(1.0 / 3.0, second.doubleValue(), 0.0);
084: }
085:
086: public void testFloatValue() {
087: Fraction first = new Fraction(1, 2);
088: Fraction second = new Fraction(1, 3);
089:
090: assertEquals(0.5f, first.floatValue(), 0.0f);
091: assertEquals((float) (1.0 / 3.0), second.floatValue(), 0.0f);
092: }
093:
094: public void testIntValue() {
095: Fraction first = new Fraction(1, 2);
096: Fraction second = new Fraction(3, 2);
097:
098: assertEquals(0, first.intValue());
099: assertEquals(1, second.intValue());
100: }
101:
102: public void testLongValue() {
103: Fraction first = new Fraction(1, 2);
104: Fraction second = new Fraction(3, 2);
105:
106: assertEquals(0L, first.longValue());
107: assertEquals(1L, second.longValue());
108: }
109:
110: public void testConstructorDouble() {
111: try {
112: assertFraction(1, 2, new Fraction(0.5));
113: assertFraction(1, 3, new Fraction(1.0 / 3.0));
114: assertFraction(17, 100, new Fraction(17.0 / 100.0));
115: assertFraction(317, 100, new Fraction(317.0 / 100.0));
116: assertFraction(-1, 2, new Fraction(-0.5));
117: assertFraction(-1, 3, new Fraction(-1.0 / 3.0));
118: assertFraction(-17, 100, new Fraction(17.0 / -100.0));
119: assertFraction(-317, 100, new Fraction(-317.0 / 100.0));
120: } catch (ConvergenceException ex) {
121: fail(ex.getMessage());
122: }
123: }
124:
125: public void testAbs() {
126: Fraction a = new Fraction(10, 21);
127: Fraction b = new Fraction(-10, 21);
128: Fraction c = new Fraction(10, -21);
129:
130: assertFraction(10, 21, a.abs());
131: assertFraction(10, 21, b.abs());
132: assertFraction(10, 21, c.abs());
133: }
134:
135: public void testReciprocal() {
136: Fraction f = null;
137:
138: f = new Fraction(50, 75);
139: f = f.reciprocal();
140: assertEquals(3, f.getNumerator());
141: assertEquals(2, f.getDenominator());
142:
143: f = new Fraction(4, 3);
144: f = f.reciprocal();
145: assertEquals(3, f.getNumerator());
146: assertEquals(4, f.getDenominator());
147:
148: f = new Fraction(-15, 47);
149: f = f.reciprocal();
150: assertEquals(-47, f.getNumerator());
151: assertEquals(15, f.getDenominator());
152:
153: f = new Fraction(0, 3);
154: try {
155: f = f.reciprocal();
156: fail("expecting ArithmeticException");
157: } catch (ArithmeticException ex) {
158: }
159:
160: // large values
161: f = new Fraction(Integer.MAX_VALUE, 1);
162: f = f.reciprocal();
163: assertEquals(1, f.getNumerator());
164: assertEquals(Integer.MAX_VALUE, f.getDenominator());
165: }
166:
167: public void testNegate() {
168: Fraction f = null;
169:
170: f = new Fraction(50, 75);
171: f = f.negate();
172: assertEquals(-2, f.getNumerator());
173: assertEquals(3, f.getDenominator());
174:
175: f = new Fraction(-50, 75);
176: f = f.negate();
177: assertEquals(2, f.getNumerator());
178: assertEquals(3, f.getDenominator());
179:
180: // large values
181: f = new Fraction(Integer.MAX_VALUE - 1, Integer.MAX_VALUE);
182: f = f.negate();
183: assertEquals(Integer.MIN_VALUE + 2, f.getNumerator());
184: assertEquals(Integer.MAX_VALUE, f.getDenominator());
185:
186: f = new Fraction(Integer.MIN_VALUE, 1);
187: try {
188: f = f.negate();
189: fail("expecting ArithmeticException");
190: } catch (ArithmeticException ex) {
191: }
192: }
193:
194: public void testAdd() {
195: Fraction a = new Fraction(1, 2);
196: Fraction b = new Fraction(2, 3);
197:
198: assertFraction(1, 1, a.add(a));
199: assertFraction(7, 6, a.add(b));
200: assertFraction(7, 6, b.add(a));
201: assertFraction(4, 3, b.add(b));
202:
203: Fraction f1 = new Fraction(Integer.MAX_VALUE - 1, 1);
204: Fraction f2 = Fraction.ONE;
205: Fraction f = f1.add(f2);
206: assertEquals(Integer.MAX_VALUE, f.getNumerator());
207: assertEquals(1, f.getDenominator());
208:
209: f1 = new Fraction(-1, 13 * 13 * 2 * 2);
210: f2 = new Fraction(-2, 13 * 17 * 2);
211: f = f1.add(f2);
212: assertEquals(13 * 13 * 17 * 2 * 2, f.getDenominator());
213: assertEquals(-17 - 2 * 13 * 2, f.getNumerator());
214:
215: try {
216: f.add(null);
217: fail("expecting IllegalArgumentException");
218: } catch (IllegalArgumentException ex) {
219: }
220:
221: // if this fraction is added naively, it will overflow.
222: // check that it doesn't.
223: f1 = new Fraction(1, 32768 * 3);
224: f2 = new Fraction(1, 59049);
225: f = f1.add(f2);
226: assertEquals(52451, f.getNumerator());
227: assertEquals(1934917632, f.getDenominator());
228:
229: f1 = new Fraction(Integer.MIN_VALUE, 3);
230: f2 = new Fraction(1, 3);
231: f = f1.add(f2);
232: assertEquals(Integer.MIN_VALUE + 1, f.getNumerator());
233: assertEquals(3, f.getDenominator());
234:
235: f1 = new Fraction(Integer.MAX_VALUE - 1, 1);
236: f2 = Fraction.ONE;
237: f = f1.add(f2);
238: assertEquals(Integer.MAX_VALUE, f.getNumerator());
239: assertEquals(1, f.getDenominator());
240:
241: try {
242: f = f.add(Fraction.ONE); // should overflow
243: fail("expecting ArithmeticException but got: "
244: + f.toString());
245: } catch (ArithmeticException ex) {
246: }
247:
248: // denominator should not be a multiple of 2 or 3 to trigger overflow
249: f1 = new Fraction(Integer.MIN_VALUE, 5);
250: f2 = new Fraction(-1, 5);
251: try {
252: f = f1.add(f2); // should overflow
253: fail("expecting ArithmeticException but got: "
254: + f.toString());
255: } catch (ArithmeticException ex) {
256: }
257:
258: try {
259: f = new Fraction(-Integer.MAX_VALUE, 1);
260: f = f.add(f);
261: fail("expecting ArithmeticException");
262: } catch (ArithmeticException ex) {
263: }
264:
265: try {
266: f = new Fraction(-Integer.MAX_VALUE, 1);
267: f = f.add(f);
268: fail("expecting ArithmeticException");
269: } catch (ArithmeticException ex) {
270: }
271:
272: f1 = new Fraction(3, 327680);
273: f2 = new Fraction(2, 59049);
274: try {
275: f = f1.add(f2); // should overflow
276: fail("expecting ArithmeticException but got: "
277: + f.toString());
278: } catch (ArithmeticException ex) {
279: }
280: }
281:
282: public void testDivide() {
283: Fraction a = new Fraction(1, 2);
284: Fraction b = new Fraction(2, 3);
285:
286: assertFraction(1, 1, a.divide(a));
287: assertFraction(3, 4, a.divide(b));
288: assertFraction(4, 3, b.divide(a));
289: assertFraction(1, 1, b.divide(b));
290:
291: Fraction f1 = new Fraction(3, 5);
292: Fraction f2 = Fraction.ZERO;
293: try {
294: Fraction f = f1.divide(f2);
295: fail("expecting ArithmeticException");
296: } catch (ArithmeticException ex) {
297: }
298:
299: f1 = new Fraction(0, 5);
300: f2 = new Fraction(2, 7);
301: Fraction f = f1.divide(f2);
302: assertSame(Fraction.ZERO, f);
303:
304: f1 = new Fraction(2, 7);
305: f2 = Fraction.ONE;
306: f = f1.divide(f2);
307: assertEquals(2, f.getNumerator());
308: assertEquals(7, f.getDenominator());
309:
310: f1 = new Fraction(1, Integer.MAX_VALUE);
311: f = f1.divide(f1);
312: assertEquals(1, f.getNumerator());
313: assertEquals(1, f.getDenominator());
314:
315: f1 = new Fraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
316: f2 = new Fraction(1, Integer.MAX_VALUE);
317: f = f1.divide(f2);
318: assertEquals(Integer.MIN_VALUE, f.getNumerator());
319: assertEquals(1, f.getDenominator());
320:
321: try {
322: f.divide(null);
323: fail("IllegalArgumentException");
324: } catch (IllegalArgumentException ex) {
325: }
326:
327: try {
328: f1 = new Fraction(1, Integer.MAX_VALUE);
329: f = f1.divide(f1.reciprocal()); // should overflow
330: fail("expecting ArithmeticException");
331: } catch (ArithmeticException ex) {
332: }
333: try {
334: f1 = new Fraction(1, -Integer.MAX_VALUE);
335: f = f1.divide(f1.reciprocal()); // should overflow
336: fail("expecting ArithmeticException");
337: } catch (ArithmeticException ex) {
338: }
339: }
340:
341: public void testMultiply() {
342: Fraction a = new Fraction(1, 2);
343: Fraction b = new Fraction(2, 3);
344:
345: assertFraction(1, 4, a.multiply(a));
346: assertFraction(1, 3, a.multiply(b));
347: assertFraction(1, 3, b.multiply(a));
348: assertFraction(4, 9, b.multiply(b));
349:
350: Fraction f1 = new Fraction(Integer.MAX_VALUE, 1);
351: Fraction f2 = new Fraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
352: Fraction f = f1.multiply(f2);
353: assertEquals(Integer.MIN_VALUE, f.getNumerator());
354: assertEquals(1, f.getDenominator());
355:
356: try {
357: f.multiply(null);
358: fail("expecting IllegalArgumentException");
359: } catch (IllegalArgumentException ex) {
360: }
361: }
362:
363: public void testSubtract() {
364: Fraction a = new Fraction(1, 2);
365: Fraction b = new Fraction(2, 3);
366:
367: assertFraction(0, 1, a.subtract(a));
368: assertFraction(-1, 6, a.subtract(b));
369: assertFraction(1, 6, b.subtract(a));
370: assertFraction(0, 1, b.subtract(b));
371:
372: Fraction f = new Fraction(1, 1);
373: try {
374: f.subtract(null);
375: fail("expecting IllegalArgumentException");
376: } catch (IllegalArgumentException ex) {
377: }
378:
379: // if this fraction is subtracted naively, it will overflow.
380: // check that it doesn't.
381: Fraction f1 = new Fraction(1, 32768 * 3);
382: Fraction f2 = new Fraction(1, 59049);
383: f = f1.subtract(f2);
384: assertEquals(-13085, f.getNumerator());
385: assertEquals(1934917632, f.getDenominator());
386:
387: f1 = new Fraction(Integer.MIN_VALUE, 3);
388: f2 = new Fraction(1, 3).negate();
389: f = f1.subtract(f2);
390: assertEquals(Integer.MIN_VALUE + 1, f.getNumerator());
391: assertEquals(3, f.getDenominator());
392:
393: f1 = new Fraction(Integer.MAX_VALUE, 1);
394: f2 = Fraction.ONE;
395: f = f1.subtract(f2);
396: assertEquals(Integer.MAX_VALUE - 1, f.getNumerator());
397: assertEquals(1, f.getDenominator());
398:
399: try {
400: f1 = new Fraction(1, Integer.MAX_VALUE);
401: f2 = new Fraction(1, Integer.MAX_VALUE - 1);
402: f = f1.subtract(f2);
403: fail("expecting ArithmeticException"); //should overflow
404: } catch (ArithmeticException ex) {
405: }
406:
407: // denominator should not be a multiple of 2 or 3 to trigger overflow
408: f1 = new Fraction(Integer.MIN_VALUE, 5);
409: f2 = new Fraction(1, 5);
410: try {
411: f = f1.subtract(f2); // should overflow
412: fail("expecting ArithmeticException but got: "
413: + f.toString());
414: } catch (ArithmeticException ex) {
415: }
416:
417: try {
418: f = new Fraction(Integer.MIN_VALUE, 1);
419: f = f.subtract(Fraction.ONE);
420: fail("expecting ArithmeticException");
421: } catch (ArithmeticException ex) {
422: }
423:
424: try {
425: f = new Fraction(Integer.MAX_VALUE, 1);
426: f = f.subtract(Fraction.ONE.negate());
427: fail("expecting ArithmeticException");
428: } catch (ArithmeticException ex) {
429: }
430:
431: f1 = new Fraction(3, 327680);
432: f2 = new Fraction(2, 59049);
433: try {
434: f = f1.subtract(f2); // should overflow
435: fail("expecting ArithmeticException but got: "
436: + f.toString());
437: } catch (ArithmeticException ex) {
438: }
439: }
440:
441: public void testEqualsAndHashCode() {
442: Fraction zero = new Fraction(0, 1);
443: Fraction nullFraction = null;
444: int zeroHash = zero.hashCode();
445: assertTrue(zero.equals(zero));
446: assertFalse(zero.equals(nullFraction));
447: assertFalse(zero.equals(new Double(0)));
448: Fraction zero2 = new Fraction(0, 2);
449: assertTrue(zero.equals(zero2));
450: assertEquals(zero.hashCode(), zero2.hashCode());
451: Fraction one = new Fraction(1, 1);
452: assertFalse((one.equals(zero) || zero.equals(one)));
453: }
454:
455: public void testGetReducedFraction() {
456: Fraction threeFourths = new Fraction(3, 4);
457: assertTrue(threeFourths.equals(Fraction
458: .getReducedFraction(6, 8)));
459: assertTrue(Fraction.ZERO.equals(Fraction.getReducedFraction(0,
460: -1)));
461: try {
462: Fraction f = Fraction.getReducedFraction(1, 0);
463: fail("expecting ArithmeticException");
464: } catch (ArithmeticException ex) {
465: // expected
466: }
467: assertEquals(Fraction.getReducedFraction(2, Integer.MIN_VALUE)
468: .getNumerator(), -1);
469: assertEquals(Fraction.getReducedFraction(1, -1).getNumerator(),
470: -1);
471: }
472: }
|