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