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