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