001 package ps1.test;
002
003 import ps1.*;
004
005 import junit.framework.TestCase;
006
007 /**
008 * This class contains a set of test cases that can be used to test the
009 * implementation of the RatNum class.
010 * <p>
011 * RatNum is implemented for you, so it should already pass all the tests in
012 * this suite. This test is provided to give you (1) examples of using the
013 * RatNum class, albeit in the context of a test driver and (2) an example of a
014 * test suite.
015 * <p>
016 */
017 public final class RatNumTest extends TestCase {
018
019 // Naming convention used throughout class: spell out number in
020 // variable as its constructive form. Unary minus is notated with
021 // the prefix "neg", and the solidus ("/") is notated with an 'I'
022 // character. Thus, "1 + 2/3" becomes "one_plus_two_I_three".
023
024 // some simple base RatNums
025 private RatNum zero = new RatNum(0);
026
027 private RatNum one = new RatNum(1);
028
029 private RatNum negOne = new RatNum(-1);
030
031 private RatNum two = new RatNum(2);
032
033 private RatNum three = new RatNum(3);
034
035 private RatNum one_I_two = new RatNum(1, 2);
036
037 private RatNum one_I_three = new RatNum(1, 3);
038
039 private RatNum one_I_four = new RatNum(1, 4);
040
041 private RatNum two_I_three = new RatNum(2, 3);
042
043 private RatNum three_I_four = new RatNum(3, 4);
044
045 private RatNum negOne_I_two = new RatNum(-1, 2);
046
047 // improper fraction
048 private RatNum three_I_two = new RatNum(3, 2);
049
050 // NaNs
051 private RatNum one_I_zero = new RatNum(1, 0);
052
053 private RatNum negOne_I_zero = new RatNum(-1, 0);
054
055 private RatNum hundred_I_zero = new RatNum(100, 0);
056
057 /**
058 * ratnums: Set of varied ratnums (includes NaNs) set is { 0, 1, -1, 2, 1/2,
059 * 3/2, 1/0, -1/0, 100/0 }
060 */
061 private RatNum[] ratNums = new RatNum[] { zero, one, negOne, two,
062 one_I_two, negOne_I_two, three_I_two,
063 /* NaNs */one_I_zero, negOne_I_zero, hundred_I_zero };
064
065 /**
066 * ratnans: Set of varied NaNs set is { 1/0, -1/0, 100/0 }
067 */
068 private RatNum[] ratNaNs = new RatNum[] { one_I_zero, negOne_I_zero,
069 hundred_I_zero };
070
071 /**
072 * ratNonNaNs: Set of varied non-NaN ratNums set is ratNums - ratNaNs
073 */
074 private RatNum[] ratNonNaNs = new RatNum[] { zero, one, negOne, two,
075 one_I_two, three_I_two };
076
077 /**
078 * This constructor is provided for junit's use.
079 */
080 public RatNumTest(String name) {
081 super(name);
082 }
083
084 /**
085 * Asserts that rep is equal to RatNum.toString. This method depends on the
086 * implementation of RatNum's "toString" and "equals" methods. Therefore,
087 * one should verify (test) those methods before using this method is in
088 * tests.
089 */
090 private void eq(RatNum ratNum, String rep) {
091 assertEquals(rep, ratNum.toString());
092 }
093
094 // The actual test cases are below.
095 //
096 // The order of the test cases is important for producing useful
097 // output. If a test uses a method of RatNum, it should test that
098 // method before hand. For example, suppose one of the test cases
099 // for "negate" is:
100 //
101 // "(new RatNum(1)).negate().equals(new RatNum(-1))"
102 //
103 // In this case, the test case relies on RatNum's "equals" method
104 // in addition to "negate"; therefore, one should test "equals"
105 // before "negate". Otherwise, it will be unclear if failing the
106 // "negate" test is due "negate" having a bug or "equals" having a
107 // bug. (Furthermore, the test depends on RatNum's constructor,
108 // so it should also be tested beforehand.)
109 //
110 // In general, it is best to have as few dependences in your test
111 // cases as possible. Doing so, will reduce the number of methods
112 // that could cause a test case to fail, making it easier to find
113 // the faulty method. In practice, one will usually need to
114 // depend on a few core methods such as the constructors and
115 // "equals" methods. Also, some of the test cases below depend on
116 // the "toString" method because it made the cases easier to write.
117 //
118 // As a secondary concern to above, if one has access to the
119 // source code of a class (as under glass box testing) one should
120 // order tests such that a method is tested after all the methods
121 // it depends on are tested. For example, in RatNum, the "sub"
122 // method calls the "negate" method; therefore, one should test
123 // "negate" before "sub". Following this methodology will make it
124 // more clear that one should fix bugs in "negate" before looking
125 // at the results of "sub" test because, "sub" could be correctly
126 // written and the "sub" test case fails only be "negate" is
127 // broken.
128 //
129 // If one does not have access to the source code (as is the case
130 // of RatTermTest and RatPolyTest, because you are proving the
131 // implementations), one can still take an educated guess as to
132 // which methods depend on other methods, but don't worry about
133 // getting it perfect.
134
135 // First, we test the constructors in isolation of (without
136 // depending on) all other RatNum methods.
137 //
138 // Unfortunately, without using any of RatNum's methods, all we
139 // can do is call the constructors and ensure that "checkRep"
140 // passes. While this is useful, it does not catch many types of
141 // errors. For example, the constructor could always return a
142 // RatNum, r, where r.numer = 1 and r.denom = 1. Being a valid
143 // RatNum, r would pass "checkRep" but would be the wrong RatNum
144 // in most cases.
145 //
146 // Given that we are unable to fully test the constructors, when
147 // any other test case fails, it could be due to an error in the
148 // constructor instead of an error in method the test case is
149 // testing.
150 //
151 // If RatNum had public fields, this problem would not exist,
152 // because we could check if the fields were set to the correct
153 // values. This problem is really a case of a more general
154 // problem of being unable to test private fields and methods of
155 // classes. For example, we are also unable to test the gcd
156 // method because it is private. Solutions to this general
157 // problem include:
158 //
159 // (1) Make the private fields and methods public. (For example,
160 // make numer, denom, and gcd public.) This in not done in
161 // general because private fields have many benefits as will
162 // be discussed in class.
163 //
164 // (2) Move the test suite code into RatNum and, thus, it would
165 // have access to private memebers. (Maybe as a static inner
166 // class [Don't worry if you don't know what this means yet.])
167 // This is not done in general because it clutters the class
168 // being tested, making it harder to understand.
169 //
170 // In practice, while testing, you may find it necessary to do (1)
171 // or (2) temporarily with a test case that accesses private
172 // fields or methods to track down a bug. But after finding the
173 // bug, remember to revert your code back. Also for future
174 // problem sets where you will be writing your own test suites,
175 // make sure that your test suite runs correctly without (1) or
176 // (2) being true.
177
178 // (Note, all of these objects were already constructed above as
179 // fields of this class (RatNumTest); thus, one could argue that
180 // this test case is redundant. We included this test case anyhow
181 // to give you an example of such a test case and because the
182 // implementation of this class could change eliminating the
183 // fields above.)
184 public void testOneArgConstructor() {
185 new RatNum(0);
186 new RatNum(1);
187 new RatNum(-1);
188 new RatNum(2);
189 new RatNum(3);
190 }
191
192 public void testTwoArgConstructor() {
193 new RatNum(1, 2);
194 new RatNum(1, 3);
195 new RatNum(1, 4);
196 new RatNum(2, 3);
197 new RatNum(3, 4);
198
199 new RatNum(-1, 2);
200
201 // improper fraction
202 new RatNum(3, 2);
203
204 // NaNs
205 new RatNum(1, 0);
206 new RatNum(-1, 0);
207 new RatNum(100, 0);
208 }
209
210 // Next, we test isNaN because it can be tested in isolation from
211 // everything except the constructors. (All instance method tests
212 // will depend on a constructor.)
213 public void testIsNaN() {
214 for (int i = 0; i < ratNaNs.length; i++) {
215 assertTrue(ratNaNs[i].isNaN());
216 }
217 for (int i = 0; i < ratNonNaNs.length; i++) {
218 assertFalse(ratNonNaNs[i].isNaN());
219 }
220 }
221
222 // Next, we test isPos and isNeg because we can easily test these
223 // methods without depending on any other methods (except the
224 // constructors).
225 private void assertPos(RatNum n) {
226 assertTrue(n.isPositive());
227 assertFalse(n.isNegative());
228 }
229
230 private void assertNeg(RatNum n) {
231 assertTrue(n.isNegative());
232 assertFalse(n.isPositive());
233 }
234
235 public void testIsPosAndIsNeg() {
236 assertFalse(zero.isPositive());
237 assertFalse(zero.isNegative());
238
239 assertPos(one);
240 assertNeg(negOne);
241 assertPos(two);
242 assertPos(three);
243
244 assertPos(one_I_two);
245 assertPos(one_I_three);
246 assertPos(one_I_four);
247 assertPos(two_I_three);
248 assertPos(three_I_four);
249
250 assertNeg(negOne_I_two);
251
252 assertPos(three_I_two);
253
254 assertPos(one_I_zero);
255 assertPos(negOne_I_zero); // non-intuitive; see spec
256 assertPos(hundred_I_zero);
257 }
258
259 // Next, we test doubleValue because the test does not require any
260 // other RatNum methods (other than constructors).
261
262 // asserts that two double's are within .0000001 of one another.
263 // It is often impossible to assert that doubles are exactly equal
264 // because of the idiosyncrasies of Java's floating point math.
265 private void approxEq(double d1, double d2) {
266 assertTrue(Math.abs(d1 - d2) < .0000001);
267 }
268
269 public void testDoubleValue() {
270 approxEq(zero.doubleValue(), 0.0);
271 approxEq(one.doubleValue(), 1.0);
272 approxEq(negOne.doubleValue(), -1.0);
273 approxEq(two.doubleValue(), 2.0);
274 approxEq(one_I_two.doubleValue(), 0.5);
275 approxEq(two_I_three.doubleValue(), 2. / 3.);
276 approxEq(three_I_four.doubleValue(), 0.75);
277
278 // cannot test that one_I_zero.doubleValue() approxEq Double.NaN,
279 // because it WON'T!!! Instead, construct corresponding
280 // instance of Double and use .equals(..) method
281 assertTrue((new Double(Double.NaN)).equals(new Double(one_I_zero
282 .doubleValue())));
283
284 // use left-shift operator "<<" to create integer for 2^30
285 RatNum one_I_twoToThirty = new RatNum(1, (1 << 30));
286 double quiteSmall = 1. / Math.pow(2, 30);
287 approxEq(one_I_twoToThirty.doubleValue(), quiteSmall);
288 }
289
290 public void testFloatValue() {
291 approxEq(zero.floatValue(), 0.0);
292 approxEq(one.floatValue(), 1.0);
293 approxEq(negOne.floatValue(), -1.0);
294 approxEq(two.floatValue(), 2.0);
295 approxEq(one_I_two.floatValue(), 0.5);
296 approxEq(two_I_three.floatValue(), 2. / 3.);
297 approxEq(three_I_four.floatValue(), 0.75);
298
299 // cannot test that one_I_zero.doubleValue() approxEq Float.NaN,
300 // because it WON'T!!! Instead, construct corresponding
301 // instance of Float and use .equals(..) method
302 assertTrue((new Float(Float.NaN)).equals(new Float(one_I_zero
303 .floatValue())));
304
305 // use left-shift operator "<<" to create integer for 2^30
306 RatNum one_I_twoToThirty = new RatNum(1, (1 << 30));
307 double quiteSmall = 1. / Math.pow(2, 30);
308 approxEq(one_I_twoToThirty.floatValue(), quiteSmall);
309 }
310
311 public void testIntValue() {
312 assertTrue("0 should round to 0", zero.intValue() == 0);
313 assertTrue("1 should round to 1", one.intValue() == 1);
314 assertTrue("-1 should round to -1", negOne.intValue() == -1);
315 assertTrue("1/2 should round to 1", one_I_two.intValue() == 1);
316 assertTrue("2/3 should round to 1", two_I_three.intValue() == 1);
317 assertTrue("3/4 should round to 1", three_I_four.intValue() == 1);
318 assertTrue("-1/2 should round to -1",
319 one_I_two.negate().intValue() == -1);
320 assertTrue("-2/3 should round to -1",
321 two_I_three.negate().intValue() == -1);
322 assertTrue("-3/4 should round to -1",
323 three_I_four.negate().intValue() == -1);
324
325 // large numbers
326 assertTrue("MAX_VALUE should round to MAX_VALUE", new RatNum(
327 Integer.MAX_VALUE).intValue() == Integer.MAX_VALUE);
328 assertTrue("MIN_VALUE should round to MIN_VALUE", new RatNum(
329 Integer.MIN_VALUE).intValue() == Integer.MIN_VALUE);
330 assertTrue("MAX_VALUE/2 should round to (MAX_VALUE/2)+1", new RatNum(
331 Integer.MAX_VALUE, 2).intValue() == (Integer.MAX_VALUE / 2) + 1);
332 assertTrue("MIN_VALUE/2 should round to (MIN_VALUE/2)", new RatNum(
333 Integer.MIN_VALUE, 2).intValue() == (Integer.MIN_VALUE / 2));
334 assertTrue("MAX_VALUE/MAX_VALUE should round to 1", new RatNum(
335 Integer.MAX_VALUE, Integer.MAX_VALUE).intValue() == 1);
336 assertTrue("MIN_VALUE/MIN_VALUE should round to 1", new RatNum(
337 Integer.MIN_VALUE, Integer.MIN_VALUE).intValue() == 1);
338
339 assertTrue("(MAX_VALUE-1)/MAX_VALUE should round to 1", new RatNum(
340 Integer.MAX_VALUE - 1, Integer.MAX_VALUE).intValue() == 1);
341 assertTrue("1/MAX_VALUE should round to 0", new RatNum(1,
342 Integer.MAX_VALUE).intValue() == 0);
343 if (false) {
344 // Note that these tests fail because our RatNum implementation
345 // can't represent the fractions in question. Can you think of
346 // a tweak to the representation invariant which would allow us
347 // to represent these values?
348 assertTrue("(MIN_VALUE+1)/MIN_VALUE should round to 1", new RatNum(
349 Integer.MIN_VALUE + 1, Integer.MIN_VALUE).intValue() == 1);
350
351 assertTrue("1/MIN_VALUE should round to 0", new RatNum(1,
352 Integer.MIN_VALUE).intValue() == 0);
353 }
354 }
355
356 // Next, we test the equals method because that can be tested in
357 // isolation from everything except the constructor and maybe
358 // isNaN, which we just tested.
359 // Additionally, this method will be very useful for testing other
360 // methods.
361
362 /**
363 * This test check is equals is reflexive. In other words that x.equals(x)
364 * is always true.
365 */
366 public void testEqualsReflexive() {
367 for (int i = 0; i < ratNums.length; i++) {
368 assertTrue(ratNums[i].equals(ratNums[i]));
369 }
370 }
371
372 public void testEquals() {
373
374 // Some simple cases.
375 assertTrue(one.equals(one));
376 assertTrue(one.add(one).equals(two));
377 // including negitives:
378 assertTrue(negOne.equals(negOne));
379
380 // Some simple cases where the objects are different but
381 // repersent the same rational number. That is, x != y but
382 // x.equals(y).
383 assertTrue((new RatNum(1, 1)).equals(new RatNum(1, 1)));
384 assertTrue((new RatNum(1, 2)).equals(new RatNum(1, 2)));
385
386 // Check that equals works on fractions that were not
387 // constructed in reduced form.
388 assertTrue(one.equals(new RatNum(2, 2)));
389 assertTrue((new RatNum(2, 2)).equals(one));
390 // including negitives:
391 assertTrue(negOne.equals(new RatNum(-9, 9)));
392 assertTrue((new RatNum(-9, 9)).equals(negOne));
393 // including double negitives:
394 assertTrue(one_I_two.equals(new RatNum(-13, -26)));
395 assertTrue((new RatNum(-13, -26)).equals(one_I_two));
396
397 // Check that all NaN's are equals to one another.
398 assertTrue(one_I_zero.equals(one_I_zero));
399 assertTrue(one_I_zero.equals(negOne_I_zero));
400 assertTrue(one_I_zero.equals(hundred_I_zero));
401
402 // Some simple cases checking for false positives.
403 assertFalse(one.equals(zero));
404 assertFalse(zero.equals(one));
405 assertFalse(one.equals(two));
406 assertFalse(two.equals(one));
407
408 // Check that equals does not neglect sign.
409 assertFalse(one.equals(negOne));
410 assertFalse(negOne.equals(one));
411
412 // Check that equals does not return false positives on
413 // fractions.
414 assertFalse(one.equals(one_I_two));
415 assertFalse(one_I_two.equals(one));
416 assertFalse(one.equals(three_I_two));
417 assertFalse(three_I_two.equals(one));
418 }
419
420 // Now that we have verified equals, we will use it in the
421 // rest or our tests.
422
423 // Next, we test the toString and valueOf methods because we can test
424 // them isolation of everything except the constructor and equals,
425 // and they will be useful methods to aid with testing other
426 // methods. (In some cases, it is easier to use valueOf("1/2") than
427 // new RatNum(1, 2) as you will see below.)
428
429 // Note that "eq" calls "toString" on its first argument.
430 public void testToStringSimple() {
431 eq(zero, "0");
432
433 eq(one, "1");
434
435 RatNum four = new RatNum(4);
436 eq(four, "4");
437
438 eq(negOne, "-1");
439
440 RatNum negFive = new RatNum(-5);
441 eq(negFive, "-5");
442
443 RatNum negZero = new RatNum(-0);
444 eq(negZero, "0");
445 }
446
447 public void testToStringFractions() {
448 RatNum one_I_two = new RatNum(1, 2);
449 eq(one_I_two, "1/2");
450
451 RatNum three_I_two = new RatNum(3, 2);
452 eq(three_I_two, "3/2");
453
454 RatNum negOne_I_thirteen = new RatNum(-1, 13);
455 eq(negOne_I_thirteen, "-1/13");
456
457 RatNum fiftyThree_I_seven = new RatNum(53, 7);
458 eq(fiftyThree_I_seven, "53/7");
459 }
460
461 public void testToStringNaN() {
462 RatNum one_I_zero = new RatNum(1, 0);
463 eq(one_I_zero, "NaN");
464
465 RatNum two_I_zero = new RatNum(2, 0);
466 eq(two_I_zero, "NaN");
467
468 RatNum negOne_I_zero = new RatNum(-1, 0);
469 eq(negOne_I_zero, "NaN");
470
471 RatNum zero_I_zero = new RatNum(0, 0);
472 eq(zero_I_zero, "NaN");
473
474 RatNum negHundred_I_zero = new RatNum(-100, 0);
475 eq(negHundred_I_zero, "NaN");
476
477 RatNum two_I_one = new RatNum(2, 1);
478 eq(two_I_one, "2");
479
480 RatNum zero_I_one = new RatNum(0, 1);
481 eq(zero_I_one, "0");
482
483 RatNum negOne_I_negTwo = new RatNum(-1, -2);
484 eq(negOne_I_negTwo, "1/2");
485
486 RatNum two_I_four = new RatNum(2, 4);
487 eq(two_I_four, "1/2");
488
489 RatNum six_I_four = new RatNum(6, 4);
490 eq(six_I_four, "3/2");
491
492 RatNum twentySeven_I_thirteen = new RatNum(27, 13);
493 eq(twentySeven_I_thirteen, "27/13");
494
495 RatNum negHundred_I_negHundred = new RatNum(-100, -100);
496 eq(negHundred_I_negHundred, "1");
497 }
498
499 // helper function, "decode-and-check"
500 private void decChk(String s, RatNum expected) {
501 RatNum.valueOf(s).equals(expected);
502 }
503
504 // Note that decChk calls valueOf.
505 public void testValueOf() {
506 decChk("0", zero);
507
508 decChk("1", one);
509 decChk("1/1", one);
510 decChk("2/2", one);
511 decChk("-1/-1", one);
512
513 decChk("-1", negOne);
514 decChk("1/-1", negOne);
515 decChk("-3/3", negOne);
516
517 decChk("2", two);
518 decChk("2/1", two);
519 decChk("-4/-2", two);
520
521 decChk("1/2", one_I_two);
522 decChk("2/4", one_I_two);
523
524 decChk("3/2", three_I_two);
525 decChk("-6/-4", three_I_two);
526
527 decChk("NaN", one_I_zero);
528 decChk("NaN", negOne_I_zero);
529 }
530
531 // Next, we test the arithmetic operations.
532 //
533 // We test them in our best guess of increasing difficultly and
534 // likelihood of having depend on a previous method. (For
535 // example, add could use sub as a subroutine.
536 //
537 // Note that our tests depend on toString and
538 // equals, which we have already tested.
539
540 public void testNegate() {
541 eq(zero.negate(), "0");
542 eq(one.negate(), "-1");
543 eq(negOne.negate(), "1");
544 eq(two.negate(), "-2");
545 eq(three.negate(), "-3");
546
547 eq(one_I_two.negate(), "-1/2");
548 eq(one_I_three.negate(), "-1/3");
549 eq(one_I_four.negate(), "-1/4");
550 eq(two_I_three.negate(), "-2/3");
551 eq(three_I_four.negate(), "-3/4");
552
553 eq(three_I_two.negate(), "-3/2");
554
555 eq(one_I_zero.negate(), "NaN");
556 eq(negOne_I_zero.negate(), "NaN");
557 eq(hundred_I_zero.negate(), "NaN");
558 }
559
560 public void testAddSimple() {
561 eq(zero.add(zero), "0");
562 eq(zero.add(one), "1");
563 eq(one.add(zero), "1");
564 eq(one.add(one), "2");
565 eq(one.add(negOne), "0");
566 eq(one.add(two), "3");
567 eq(two.add(two), "4");
568 }
569
570 public void testAddComplex() {
571 eq(one_I_two.add(zero), "1/2");
572 eq(one_I_two.add(one), "3/2");
573 eq(one_I_two.add(one_I_two), "1");
574 eq(one_I_two.add(one_I_three), "5/6");
575 eq(one_I_two.add(negOne), "-1/2");
576 eq(one_I_two.add(two), "5/2");
577 eq(one_I_two.add(two_I_three), "7/6");
578 eq(one_I_two.add(three_I_four), "5/4");
579
580 eq(one_I_three.add(zero), "1/3");
581 eq(one_I_three.add(two_I_three), "1");
582 eq(one_I_three.add(three_I_four), "13/12");
583 }
584
585 public void testAddImproper() {
586 eq(three_I_two.add(one_I_two), "2");
587 eq(three_I_two.add(one_I_three), "11/6");
588 eq(three_I_four.add(three_I_four), "3/2");
589
590 eq(three_I_two.add(three_I_two), "3");
591 }
592
593 public void testAddOnNaN() {
594 // each test case (addend, augend) drawn from the set
595 // ratNums x ratNaNs
596
597 for (int i = 0; i < ratNums.length; i++) {
598 for (int j = 0; j < ratNaNs.length; j++) {
599 eq(ratNums[i].add(ratNaNs[j]), "NaN");
600 eq(ratNaNs[j].add(ratNums[i]), "NaN");
601 }
602 }
603
604 }
605
606 public void testAddTransitively() {
607 eq(one.add(one).add(one), "3");
608 eq(one.add(one.add(one)), "3");
609 eq(zero.add(zero).add(zero), "0");
610 eq(zero.add(zero.add(zero)), "0");
611 eq(one.add(two).add(three), "6");
612 eq(one.add(two.add(three)), "6");
613
614 eq(one_I_three.add(one_I_three).add(one_I_three), "1");
615 eq(one_I_three.add(one_I_three.add(one_I_three)), "1");
616
617 eq(one_I_zero.add(one_I_zero).add(one_I_zero), "NaN");
618 eq(one_I_zero.add(one_I_zero.add(one_I_zero)), "NaN");
619
620 eq(one_I_two.add(one_I_three).add(one_I_four), "13/12");
621 eq(one_I_two.add(one_I_three.add(one_I_four)), "13/12");
622 }
623
624 public void testSubSimple() {
625 eq(zero.sub(one), "-1");
626 eq(zero.sub(zero), "0");
627 eq(one.sub(zero), "1");
628 eq(one.sub(one), "0");
629 eq(two.sub(one), "1");
630 eq(one.sub(negOne), "2");
631 eq(one.sub(two), "-1");
632 eq(one.sub(three), "-2");
633 }
634
635 public void testSubComplex() {
636 eq(one.sub(one_I_two), "1/2");
637 eq(one_I_two.sub(one), "-1/2");
638 eq(one_I_two.sub(zero), "1/2");
639 eq(one_I_two.sub(two_I_three), "-1/6");
640 eq(one_I_two.sub(three_I_four), "-1/4");
641 }
642
643 public void testSubImproper() {
644 eq(three_I_two.sub(one_I_two), "1");
645 eq(three_I_two.sub(one_I_three), "7/6");
646 }
647
648 public void testSubOnNaN() {
649 // analogous to testAddOnNaN()
650
651 for (int i = 0; i < ratNums.length; i++) {
652 for (int j = 0; j < ratNaNs.length; j++) {
653 eq(ratNums[i].sub(ratNaNs[j]), "NaN");
654 eq(ratNaNs[j].sub(ratNums[i]), "NaN");
655 }
656 }
657 }
658
659 public void testSubTransitively() {
660 // subtraction is not transitive; testing that operation is
661 // correct when *applied transitivitely*, not that it obeys
662 // the transitive property
663
664 eq(one.sub(one).sub(one), "-1");
665 eq(one.sub(one.sub(one)), "1");
666 eq(zero.sub(zero).sub(zero), "0");
667 eq(zero.sub(zero.sub(zero)), "0");
668 eq(one.sub(two).sub(three), "-4");
669 eq(one.sub(two.sub(three)), "2");
670
671 eq(one_I_three.sub(one_I_three).sub(one_I_three), "-1/3");
672 eq(one_I_three.sub(one_I_three.sub(one_I_three)), "1/3");
673
674 eq(one_I_zero.sub(one_I_zero).sub(one_I_zero), "NaN");
675 eq(one_I_zero.sub(one_I_zero.sub(one_I_zero)), "NaN");
676
677 eq(one_I_two.sub(one_I_three).sub(one_I_four), "-1/12");
678 eq(one_I_two.sub(one_I_three.sub(one_I_four)), "5/12");
679 }
680
681 public void testMulProperties() {
682 // zero property
683 for (int i = 0; i < ratNonNaNs.length; i++) {
684 eq(zero.mul(ratNonNaNs[i]), "0");
685 eq(ratNonNaNs[i].mul(zero), "0");
686 }
687
688 // one property
689 for (int i = 0; i < ratNonNaNs.length; i++) {
690 eq(one.mul(ratNonNaNs[i]), ratNonNaNs[i].toString());
691 eq(ratNonNaNs[i].mul(one), ratNonNaNs[i].toString());
692 }
693
694 // negOne property
695 for (int i = 0; i < ratNonNaNs.length; i++) {
696 eq(negOne.mul(ratNonNaNs[i]), ratNonNaNs[i].negate().toString());
697 eq(ratNonNaNs[i].mul(negOne), ratNonNaNs[i].negate().toString());
698 }
699 }
700
701 public void testMulSimple() {
702 eq(two.mul(two), "4");
703 eq(two.mul(three), "6");
704 eq(three.mul(two), "6");
705 }
706
707 public void testMulComplex() {
708 eq(one_I_two.mul(two), "1");
709 eq(two.mul(one_I_two), "1");
710 eq(one_I_two.mul(one_I_two), "1/4");
711 eq(one_I_two.mul(one_I_three), "1/6");
712 eq(one_I_three.mul(one_I_two), "1/6");
713 }
714
715 public void testMulImproper() {
716 eq(three_I_two.mul(one_I_two), "3/4");
717 eq(three_I_two.mul(one_I_three), "1/2");
718 eq(three_I_two.mul(three_I_four), "9/8");
719 eq(three_I_two.mul(three_I_two), "9/4");
720 }
721
722 public void testMulOnNaN() {
723 // analogous to testAddOnNaN()
724
725 for (int i = 0; i < ratNums.length; i++) {
726 for (int j = 0; j < ratNaNs.length; j++) {
727 eq(ratNums[i].mul(ratNaNs[j]), "NaN");
728 eq(ratNaNs[j].mul(ratNums[i]), "NaN");
729 }
730 }
731 }
732
733 public void testMulTransitively() {
734 eq(one.mul(one).mul(one), "1");
735 eq(one.mul(one.mul(one)), "1");
736 eq(zero.mul(zero).mul(zero), "0");
737 eq(zero.mul(zero.mul(zero)), "0");
738 eq(one.mul(two).mul(three), "6");
739 eq(one.mul(two.mul(three)), "6");
740
741 eq(one_I_three.mul(one_I_three).mul(one_I_three), "1/27");
742 eq(one_I_three.mul(one_I_three.mul(one_I_three)), "1/27");
743
744 eq(one_I_zero.mul(one_I_zero).mul(one_I_zero), "NaN");
745 eq(one_I_zero.mul(one_I_zero.mul(one_I_zero)), "NaN");
746
747 eq(one_I_two.mul(one_I_three).mul(one_I_four), "1/24");
748 eq(one_I_two.mul(one_I_three.mul(one_I_four)), "1/24");
749 }
750
751 public void testDivSimple() {
752 eq(zero.div(zero), "NaN");
753 eq(zero.div(one), "0");
754 eq(one.div(zero), "NaN");
755 eq(one.div(one), "1");
756 eq(one.div(negOne), "-1");
757 eq(one.div(two), "1/2");
758 eq(two.div(two), "1");
759 }
760
761 public void testDivComplex() {
762 eq(one_I_two.div(zero), "NaN");
763 eq(one_I_two.div(one), "1/2");
764 eq(one_I_two.div(one_I_two), "1");
765 eq(one_I_two.div(one_I_three), "3/2");
766 eq(one_I_two.div(negOne), "-1/2");
767 eq(one_I_two.div(two), "1/4");
768 eq(one_I_two.div(two_I_three), "3/4");
769 eq(one_I_two.div(three_I_four), "2/3");
770
771 eq(one_I_three.div(zero), "NaN");
772 eq(one_I_three.div(two_I_three), "1/2");
773 eq(one_I_three.div(three_I_four), "4/9");
774 }
775
776 public void testDivImproper() {
777 eq(three_I_two.div(one_I_two), "3");
778 eq(three_I_two.div(one_I_three), "9/2");
779 eq(three_I_two.div(three_I_two), "1");
780 }
781
782 public void testDivOnNaN() {
783 // each test case (addend, augend) drawn from the set
784 // ratNums x ratNaNs
785
786 for (int i = 0; i < ratNums.length; i++) {
787 for (int j = 0; j < ratNaNs.length; j++) {
788 eq(ratNums[i].div(ratNaNs[j]), "NaN");
789 eq(ratNaNs[j].div(ratNums[i]), "NaN");
790 }
791 }
792
793 }
794
795 public void testDivTransitively() {
796 // (same note as in testSubTransitively re: transitivity property)
797
798 eq(one.div(one).div(one), "1");
799 eq(one.div(one.div(one)), "1");
800 eq(zero.div(zero).div(zero), "NaN");
801 eq(zero.div(zero.div(zero)), "NaN");
802 eq(one.div(two).div(three), "1/6");
803 eq(one.div(two.div(three)), "3/2");
804
805 eq(one_I_three.div(one_I_three).div(one_I_three), "3");
806 eq(one_I_three.div(one_I_three.div(one_I_three)), "1/3");
807
808 eq(one_I_zero.div(one_I_zero).div(one_I_zero), "NaN");
809 eq(one_I_zero.div(one_I_zero.div(one_I_zero)), "NaN");
810
811 eq(one_I_two.div(one_I_three).div(one_I_four), "6");
812 eq(one_I_two.div(one_I_three.div(one_I_four)), "3/8");
813
814 }
815
816 // Finally, we test compare. We do so last, because compare may
817 // depend on sub, isNaN, and/or equals, so we want to test those
818 // methods first.
819
820 private void assertGreater(RatNum larger, RatNum smaller) {
821 assertTrue(larger.compareTo(smaller) > 0);
822 assertTrue(smaller.compareTo(larger) < 0);
823 }
824
825 public void testCompareToReflexive() {
826 // reflexivitiy: x.compare(x) == 0.
827 for (int i = 0; i < ratNums.length; i++) {
828 assertTrue(ratNums[i].equals(ratNums[i]));
829 }
830 }
831
832 public void testCompareToNonFract() {
833 assertGreater(one, zero);
834 assertGreater(one, negOne);
835 assertGreater(two, one);
836 assertGreater(two, zero);
837 assertGreater(zero, negOne);
838 }
839
840 public void testCompareToFract() {
841 assertGreater(one, one_I_two);
842 assertGreater(two, one_I_three);
843 assertGreater(one, two_I_three);
844 assertGreater(two, two_I_three);
845 assertGreater(one_I_two, zero);
846 assertGreater(one_I_two, negOne);
847 assertGreater(one_I_two, negOne_I_two);
848 assertGreater(zero, negOne_I_two);
849 }
850
851 public void testCompareToNaNs() {
852 for (int i = 0; i < ratNaNs.length; i++) {
853 for (int j = 0; j < ratNaNs.length; j++) {
854 assertTrue(ratNaNs[i].equals(ratNaNs[j]));
855 }
856 for (int j = 0; j < ratNonNaNs.length; j++) {
857 assertGreater(ratNaNs[i], ratNonNaNs[j]);
858 }
859 }
860 }
861
862 }