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