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 }