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 }