// import becker.robots.*; // import java.util.Random; /** A class of code for testing arithmetic * * @author Duncan Buell * * These are simple rules to demonstrate arithmetic and precision of * arithmetic values. * * written: 14 October 2007 * **/ public class TestCode { /* **************************************************************************** */ /** Put in a constructor just in case I want one later. **/ public TestCode() { } /* **************************************************************************** */ /** test the integer arithmetic size * * Integers on the machines I happen to be using seem to be 32 bits and seem * to use twos-complement notation. This just sets up a loop multiplying an * integer by 2 repetitively. No error is generated when the multiplication * suddenly produces a garbage result. * * The integer 2 is bit pattern 00000000 00000000 00000000 00000010 * (spaces inserted for readability) * Multiplying by 2 is the same as a shift left to produce * bit pattern 00000000 00000000 00000000 00000100 * by 2 again to produce pattern 00000000 00000000 00000000 00001000 * and so forth. When the pattern goes from * 01000000 00000000 00000000 00000000 * to 10000000 00000000 00000000 00000000 * then the number represented goes from 2^30 to -2^31, and then * when one multiplies yet again by 2 the pattern becomes all zeros. * * With negative numbers the story is ever so slightly different. * Minus 2 is represented by 11111111 11111111 11111111 11111110 * so multiplication by 2 continues to be a shift left of the bit * pattern, but in this case the number that is represented is in * fact the correct number up until the pattern becomes all zeros. * **/ public void doIntegerTest() { int theNumberBefore,theNumberAfter; System.out.println(""); System.out.println("Test of positive integer arithmetic sizes"); theNumberBefore = 1; theNumberAfter = 1; for(int i = 1; i <= 32; ++i) { theNumberAfter = theNumberBefore * 2; System.out.println("i=" + i + " Before=" + theNumberBefore + ", After=" + theNumberAfter + " is 2^" + i); theNumberBefore = theNumberAfter; } // for(int i = 1; i <= 32; ++i) System.out.println(""); System.out.println("Test of negative integer arithmetic sizes"); theNumberBefore = -1; theNumberAfter = -1; for(int i = 1; i <= 32; ++i) { theNumberAfter = theNumberBefore * 2; System.out.println("i=" + i + " Before=" + theNumberBefore + ", After=" + theNumberAfter + " is -2^" + i); theNumberBefore = theNumberAfter; } // for(int i = 1; i <= 32; ++i) } // public void doIntegerTest(); /* **************************************************************************** */ /** test the double precision point arithmetic size * All this shows is that doubles are not like integers. We don't get the * erroneous change from positive to negative to zero. What we would get, if * we continued to multiply up, is that we get the most significant digits of * the product, not the least significant digits. **/ public void doDoubleTest1() { double theNumberBefore,theNumberAfter; System.out.println(""); System.out.println("Test 1 of positive double precision arithmetic sizes"); theNumberBefore = 1.0; theNumberAfter = 1.0; for(int i = 1; i <= 32; ++i) { theNumberAfter = theNumberBefore * 2.0; System.out.println("i=" + i + " Before=" + theNumberBefore + ", After=" + theNumberAfter + " is 2.0^" + i); theNumberBefore = theNumberAfter; } // for(int i = 1; i <= 32; ++i) System.out.println(""); System.out.println("Test 1 of negative double precision arithmetic sizes"); theNumberBefore = -1.0; theNumberAfter = -1.0; for(int i = 1; i <= 32; ++i) { theNumberAfter = theNumberBefore * 2.0; System.out.println("i=" + i + " Before=" + theNumberBefore + ", After=" + theNumberAfter + " is -2.0^" + i); theNumberBefore = theNumberAfter; } // for(int i = 1; i <= 32; ++i) } // public void doDoubleTest1(); /* **************************************************************************** */ /** Test the double precision point arithmetic size * This test demonstrates double precision sizes * If we just square a number repeatedly, it eventually gets too large to be * represented. In Java, on these machines, the result is that "Infinity" is * the answer. **/ public void doDoubleTest2() { double theNumberBefore,theNumberAfter; System.out.println(""); System.out.println("Test 2 of double precision arithmetic sizes"); theNumberBefore = 2.0; theNumberAfter = 2.0; for(int i = 1; i <= 12; ++i) { theNumberAfter = theNumberBefore * theNumberBefore; System.out.println("i=" + i + " Before=" + theNumberBefore + ", After=" + theNumberAfter + " is Before^2"); theNumberBefore = theNumberAfter; } // for(int i = 1; i <= 12; ++i) } // public void doDoubleTest2(); /* **************************************************************************** */ /** Test the double precision point arithmetic size * This test demonstrates double precision sizes * In IEEE 754 arithmetic, you get 52 bits with which to represent the * significand of a double precision value. * What this program does is require the representation of a number that needs * more and more precision. * The decimal number 1.5 is binary 1.1, or 0.11 * 2^{-1} * The decimal number 1.25 is binary 1.01, or 0.101 * 2^{-1} * The decimal number 1.125 is binary 1.001, or 0.1001 * 2^{-1} * The decimal number 1.0625 is binary 1.0001, or 0.10001 * 2^{-1} * If we keep going, eventually we require a number with a 1 at the left edge * and a 1 at the right edge with the right edge too many bits to the right. * Since we are keeping the MOST significant part of the number, we throw away * the tiny part at the right edge, which causes the number to be rounded down * to 1.0. **/ public void doDoubleTest3() { double theAddin, theBaseNumber,theSum; System.out.println(""); System.out.println("Test 3 of double precision arithmetic sizes"); theBaseNumber= 1.0; theAddin = 1.0; for(int i = 1; i <= 53; ++i) { theAddin = theAddin / 2.0; theSum = theBaseNumber + theAddin; System.out.println("i=" + i + " Base=" + theBaseNumber + " plus Addin=" + theAddin + " equals " + theSum); } // for(int i = 1; i <= 53; ++i) } // public void doDoubleTest3(); } // public class TestCode