Primes.java: New file.
authorAnthony Green <green@cygnus.com>
Mon, 9 Aug 1999 06:35:56 +0000 (06:35 +0000)
committerAnthony Green <green@gcc.gnu.org>
Mon, 9 Aug 1999 06:35:56 +0000 (06:35 +0000)
* libjava.lang/Primes.java: New file.
* libjava.lang/Primes.out: New file.

From-SVN: r28613

libjava/testsuite/ChangeLog
libjava/testsuite/libjava.lang/Primes.java [new file with mode: 0644]
libjava/testsuite/libjava.lang/Primes.out [new file with mode: 0644]

index 49794b1..7b35bc1 100644 (file)
@@ -1,3 +1,8 @@
+1999-08-09  Anthony Green  <green@cygnus.com>
+
+       * libjava.lang/Primes.java: New file.
+       * libjava.lang/Primes.out: New file.
+
 1999-07-31  Alexandre Oliva  <oliva@dcc.unicamp.br>
 
        * lib/libjava.exp (bytecompile_file): Use `env(SUN_JAVAC)', that
diff --git a/libjava/testsuite/libjava.lang/Primes.java b/libjava/testsuite/libjava.lang/Primes.java
new file mode 100644 (file)
index 0000000..d6e4336
--- /dev/null
@@ -0,0 +1,213 @@
+// Primes.java\r
+\r
+/** Copyright 1998\r
+ * Roedy Green\r
+ * Canadian Mind Products\r
+ * 5317 Barker Avenue\r
+ * Burnaby, BC Canada V5H 2N6\r
+ * tel: (604) 435-3016\r
+ * mailto:roedy@mindprod.com\r
+ * http://mindprod.com\r
+ */\r
+// May be freely distributed for any purpose but military\r
+\r
+import java.util.BitSet;\r
+\r
+/**\r
+  * @author Roedy Green\r
+  * @version 1.10 1998 November 10\r
+  * Calculate primes using Eratostheses Sieve.\r
+  * Tell if a given number is prime.\r
+  * Find a prime just below a given number.\r
+  * Find a prime just above a given number.\r
+  */\r
+  \r
+/* \r
+ * version 1.1 1998 November 10 - new address and phone.  \r
+ */\r
+class Primes\r
+    {\r
+\r
+    /**\r
+      * constructors\r
+      */\r
+    Primes()\r
+        {\r
+        ensureCapacity(1000);\r
+        }\r
+\r
+    /**\r
+      * @param capacity - largest number you will be asking if prime.\r
+      * If give too small a number, it will automatically grow by\r
+      * recomputing the sieve array.\r
+      */\r
+    Primes (int capacity)\r
+        {\r
+        ensureCapacity(capacity);\r
+        }\r
+\r
+    /**\r
+      * @param candidate - is this a prime?\r
+      */\r
+    public boolean isPrime(int candidate)\r
+        {\r
+        ensureCapacity(candidate);\r
+        if (candidate < 3) return candidate != 0;\r
+        if (candidate % 2 == 0 ) return false;\r
+        return !b.get(candidate/2);\r
+        }\r
+\r
+    /**\r
+      * @return first prime higher than candidate\r
+      */\r
+    public int above(int candidate)\r
+    {\r
+        do\r
+            {\r
+            // see what we can find in the existing sieve\r
+            for (int i=candidate+1; i<= sieveCapacity; i++)\r
+                {\r
+                if (isPrime(i)) return i;\r
+                }\r
+            // Keep building ever bigger sieves till we succeed.\r
+            // The next prime P' is between P+2 and P^2 - 2.\r
+            // However that is a rather pessimistic upper bound.\r
+            // Ideally some theorem would tell us how big we need to build\r
+            // to find one.\r
+            ensureCapacity(Math.max(candidate*2, sieveCapacity*2));\r
+            } // end do\r
+        while (true);\r
+        } // end above\r
+\r
+    /**\r
+      * @param return first prime less than candidate\r
+      */\r
+    public int below (int candidate)\r
+    {\r
+        for (candidate--; candidate > 0; candidate--)\r
+            {\r
+            if (isPrime(candidate)) return candidate;\r
+            }\r
+        // candidate was 1 or 0 or -ve\r
+        return 0;\r
+        }\r
+\r
+    /**\r
+      * calc all primes in the range 1..n,\r
+      * not the first n primes.\r
+      * @param n, highest candidate, not necessarily prime.\r
+      * @return list of primes 1..n in an array\r
+      */\r
+    public final int[] getPrimes(int n)\r
+        {\r
+        // calculate the primes\r
+        ensureCapacity(n);\r
+\r
+        // pass 1: count primes\r
+        int countPrimes = 0;\r
+        for (int i = 0; i <= n; i++)\r
+            {\r
+            if (isPrime(i)) countPrimes++;\r
+            }\r
+\r
+        // pass 2: construct array of primes\r
+        int [] primes = new int[countPrimes];\r
+        countPrimes = 0;\r
+        for (int i = 0; i <= n; i++)\r
+            {\r
+            if (isPrime(i)) primes[countPrimes++] = i;\r
+            }\r
+        return primes;\r
+        } // end getPrimes\r
+\r
+    /**\r
+      * calculate the sieve, bit map of all primes 0..n\r
+      * @param n highest number evalutated by the sieve, not necessarily prime.\r
+      */\r
+    private final void sieve ( int n )\r
+        {\r
+        // Presume BitSet b set is big enough for our purposes.\r
+        // Presume all even numbers are already marked composite, effectively.\r
+        // Presume all odd numbers are already marked prime (0 in bit map).\r
+        int last = (int)(Math.sqrt(n))+1;\r
+        for (int candidate = 3; candidate <= last; candidate += 2)\r
+            {\r
+            // only look at odd numbers\r
+            if (!b.get(candidate/2) /* if candidate is prime */)\r
+                {\r
+                // Our candidate is prime.\r
+                // Only bother to mark multiples of primes. Others already done.\r
+                // no need to mark even multiples, already done\r
+                int incr = candidate*2;\r
+                for ( int multiple = candidate + incr; multiple < n; multiple += incr)\r
+                    {\r
+                    b.set(multiple/2); // mark multiple as composite\r
+                    } // end for multiple\r
+                } // end if\r
+            } // end for candidate\r
+        // at this point our sieve b is correct, except for 0..2\r
+        } // end sieve\r
+\r
+    /**\r
+      * Ensure have a sieve to tackle primes as big as n.\r
+      * If we don't allocate a sieve big enough and calculate it.\r
+      * @param n - ensure sieve big enough to evaluate n for primality.\r
+      */\r
+    private void ensureCapacity (int n)\r
+        {\r
+        if ( n > sieveCapacity )\r
+            {\r
+            b = new BitSet((n+1)/2);\r
+            // starts out all 0, presume all numbers prime\r
+            sieveCapacity = n;\r
+            sieve(n);\r
+            }\r
+        // otherwise existing sieve is fine\r
+        } // end ensureCapacity\r
+\r
+    private int sieveCapacity;\r
+    // biggest number we have computed in our sieve.\r
+    // our BitSet array is indexed 0..N (odd only)\r
+\r
+    private BitSet b; /* true for each odd number if is composite */\r
+\r
+    /**\r
+      * Demonstrate and test the methods\r
+      */\r
+    public static void main (String[] args)\r
+        {\r
+        // print primes 1..101\r
+        Primes calc = new Primes(106);\r
+        int[] primes = calc.getPrimes(101);\r
+        for (int i=0; i<primes.length; i++)\r
+            {\r
+            System.out.println(primes[i]);\r
+            }\r
+\r
+        // demonstrate isPrime, above, below\r
+        System.out.println(calc.isPrime(149));\r
+        System.out.println(calc.below(149));\r
+        System.out.println(calc.above(149));\r
+\r
+        // print all the primes just greater than powers of 2\r
+        calc = new Primes(10000000);\r
+        for (int pow=8; pow < 10000000; pow*=2)\r
+            System.out.println(calc.above(pow));\r
+\r
+        // Validate that isPrime works by comparing it with brute force\r
+        for (int i=3; i<=151; i++)\r
+            {\r
+            boolean prime = true;\r
+            for (int j=2; j<i; j++)\r
+                {\r
+                if (i % j == 0 )\r
+                    {\r
+                    prime = false;\r
+                    break;\r
+                    }\r
+                } // end for j\r
+            if ( calc.isPrime(i) != prime ) System.out.println(i + " oops");\r
+            } // end for i\r
+\r
+        } // end main\r
+} // end Primes\r
diff --git a/libjava/testsuite/libjava.lang/Primes.out b/libjava/testsuite/libjava.lang/Primes.out
new file mode 100644 (file)
index 0000000..279398b
--- /dev/null
@@ -0,0 +1,51 @@
+1
+2
+3
+5
+7
+11
+13
+17
+19
+23
+29
+31
+37
+41
+43
+47
+53
+59
+61
+67
+71
+73
+79
+83
+89
+97
+101
+true
+139
+151
+11
+17
+37
+67
+131
+257
+521
+1031
+2053
+4099
+8209
+16411
+32771
+65537
+131101
+262147
+524309
+1048583
+2097169
+4194319
+8388617