Re: Beginner Projects



On Wed, 29 Aug 2007 21:23:06 +0000 (UTC), Pseudo Silk Kimono
<Pseudo_Silk_Kimono@xxxxxxxxxxxxx> wrote, quoted or indirectly quoted
someone who said :

I would be eager to hear of any suggested improvments.

Here is my code. I'm the guy who composed the list of projects:
The complete code is posted at
http://mindprod.com/products2.html#PRIMES


/* calculate primes

copyright (c) 1998-2007 Roedy Green, Canadian Mind Products
may be copied and used freely for any purpose but military.

Roedy Green
Canadian Mind Products
#101 - 2536 Wark Street
Victoria, BC Canada
V8T 4G8
tel: (250) 361-9093
mailto:roedyg@xxxxxxxxxxxx
http://mindprod.com

version History

1.1 1998-11-10 Calculate primes using Eratostheses Sieve.
Tell if a given number is prime. Find a prime just below a given
number. Find a prime just above a given number.
new address and phone.

1.2 2006-01-29 - import to Eclipse and tidy.

1.4 20067-03-06 - reformat with IntelliJ, add Javadoc.
*/
package com.mindprod.primes;

import java.util.BitSet;

/**
* Caluculate primes, and primes near other numbers.
*
* @author Roedy Green, Canadian Mind Products
* @version 1.4, 2006-03-06
*/
class Primes {

// ------------------------------ FIELDS
------------------------------

/**
* not displayed copyright
*/
public static final String EMBEDDEDCOPYRIGHT =
"copyright (c) 1997-2007 Roedy Green, Canadian Mind
Products, http://mindprod.com";;

private static final String RELEASEDATE = "2006-03-06";

/**
* embedded version string.
*/
public static final String VERSIONSTRING = "1.4";

/**
* true for each odd number if is composite
*/
private BitSet b;

/**
* how many elements max in the seize arra
*/
private int sieveCapacity;

// -------------------------- PUBLIC INSTANCE METHODS
--------------------------
/**
* @param candidate number you want to find a prime near.
*
* @return first prime higher than candidate
*/
public int above( int candidate )
{
do
{
// see what we can find in the existing sieve
for ( int i = candidate + 1; i <= sieveCapacity; i++ )
{
if ( isPrime( i ) )
{
return i;
}
}
// Keep building ever bigger sieves till we succeed.
// The next prime P' is between P+2 and P^2 - 2.
// However that is a rather pessimistic upper bound.
// Ideally some theorem would tell us how big we need to
build
// to find one.
ensureCapacity( Math.max( candidate * 2, sieveCapacity * 2
) );
}// end do
while ( true );
}// end above

/**
* @param candidate number you want to find a prime near.
*
* @return first prime less than candidate
*/
public int below( int candidate )
{
for ( candidate--; candidate > 0; candidate-- )
{
if ( isPrime( candidate ) )
{
return candidate;
}
}
// candidate was 1 or 0 or -ve
return 0;
}

/**
* calc all primes in the range 1..n, not the first n primes.
*
* @param n highest candidate, not necessarily prime.
*
* @return list of primes 1..n in an array
*/
public final int[] getPrimes( int n )
{
// calculate the primes
ensureCapacity( n );

// pass 1: count primes
int countPrimes = 0;
for ( int i = 0; i <= n; i++ )
{
if ( isPrime( i ) )
{
countPrimes++;
}
}

// pass 2: construct array of primes
int[] primes = new int[countPrimes];
countPrimes = 0;
for ( int i = 0; i <= n; i++ )
{
if ( isPrime( i ) )
{
primes[ countPrimes++ ] = i;
}
}
return primes;
}// end getPrimes

/**
* @param candidate - is this a prime?
*
* @return true if this number is prime
*/
public boolean isPrime( int candidate )
{
ensureCapacity( candidate );
if ( candidate < 3 )
{
return candidate != 0;
}
if ( candidate % 2 == 0 )
{
return false;
}
return !b.get( candidate / 2 );
}

// --------------------------- CONSTRUCTORS
---------------------------

/**
* constructors
*/
Primes()
{
ensureCapacity( 1000 );
}

/**
* @param capacity - largest number you will be asking if prime.
If give too
* small a number, it will automatically grow by
recomputing
* the sieve array.
*/
Primes( int capacity )
{
ensureCapacity( capacity );
}

// -------------------------- OTHER METHODS
--------------------------

// biggest number we have computed in our sieve.
// our BitSet array is indexed 0..N (odd only)

/**
* Ensure have a sieve to tackle primes as big as n. If we don't
allocate a
* sieve big enough and calculate it.
*
* @param n - ensure sieve big enough to evaluate n for primality.
*/
private void ensureCapacity( int n )
{
if ( n > sieveCapacity )
{
b = new BitSet( ( n + 1 ) / 2 );
// starts out all 0, presume all numbers prime
sieveCapacity = n;
sieve( n );
}
// otherwise existing sieve is fine
}// end ensureCapacity

/**
* calculate the sieve, bit map of all primes 0..n
*
* @param n highest number evalutated by the sieve, not
necessarily prime.
*/
private void sieve( int n )
{
// Presume BitSet b set is big enough for our purposes.
// Presume all even numbers are already marked composite,
effectively.
// Presume all odd numbers are already marked prime (0 in bit
map).
int last = (int) ( Math.sqrt( n ) ) + 1;
for ( int candidate = 3; candidate <= last; candidate += 2 )
{
// only look at odd numbers
if ( !b.get( candidate / 2 )/* if candidate is prime */ )
{
// Our candidate is prime.
// Only bother to mark multiples of primes. Others
already done.
// no need to mark even multiples, already done
int incr = candidate * 2;
for ( int multiple = candidate + incr; multiple < n;
multiple +=
incr )
{
b.set( multiple / 2 );// mark multiple as
composite
}// end for multiple
}// end if
}// end for candidate
// at this point our sieve b is correct, except for 0..2
}// end sieve

// --------------------------- main() method
---------------------------

/**
* Demonstrate and test the methods
*
* @param args not used
*/
public static void main( String[] args )
{
System.out.println( "primes under 10,000" );
Primes calc = new Primes( 10000 );
int[] primes = calc.getPrimes( 10000 );
for ( int i = 0; i < primes.length; i++ )
{
System.out.println( primes[ i ] );
}

// demonstrate isPrime, above, below
System.out.println( "Is 149 prime? " + calc.isPrime( 149 ) );
System.out
.println( "The prime just below 149 is " + calc.below(
149 ) );
System.out
.println( "The prime just above 149 is " + calc.above(
149 ) );

System.out.println( "Primes just larger than 2^n" );
calc = new Primes( 10000000 );
for ( int pow = 8; pow < 10000000; pow *= 2 )
{
System.out.println( calc.above( pow ) );
}

System.out
.println(
"Validating that isPrime works by comparing it
with brute force successive division." );
for ( int i = 3; i <= 151; i++ )
{
boolean prime = true;
for ( int j = 2; j < i; j++ )
{
if ( i % j == 0 )
{
prime = false;
break;
}
}// end for j
if ( calc.isPrime( i ) != prime )
{
System.out
.println( i
+ " oops: algorithms give different
answers" );
}
}// end for i
System.out.println( "done" );
}// end main
}// end Primes
--
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
.



Relevant Pages

  • Re: greatest multiple algorithm
    ... Bernstein or Galway's quadratic form sieve rather than ... lower or smaller primes in bit sieve. ... slower with larger sieve sizes due to the large number of memory accesses. ... You can use a wheel to decrease the memory requirements. ...
    (comp.lang.asm.x86)
  • Re: greatest multiple algorithm
    ... Bernstein or Galway's quadratic form sieve rather than ... lower or smaller primes in bit sieve. ... slows down based on size memory used ... You can use a wheel to decrease the memory requirements. ...
    (comp.lang.asm.x86)
  • Re: Prime number algorithm in C
    ... Here is a sieve that computes the first ULONG_MAX primes or until it runs out ... static void *heap{ ... static int decrement{ ...
    (comp.programming)
  • Re: How to write a efficient Sieve of Eratosthenes algorithm in lisp?
    ... the ultimate test is to find primes in range 999900000 - ... Also, my sieve algorithm is n log, so even if the space ... (loop for x from (start-index n) ... Real time: 0.4375 sec. ...
    (comp.lang.lisp)
  • Re: As the Crow flies.
    ... Almost any sieve would do. ... counting primes < 1000000 ... mark.c:50: warning: return type defaults to ?int? ... mark.c:56: warning: format ?%lld? ...
    (talk.origins)