Commit 2138baab authored by Niels Möller's avatar Niels Möller
Browse files

Removed features.

Rev: nettle/examples/eratosthenes.c:1.5
parent a3985305
...@@ -52,22 +52,17 @@ usage(void) ...@@ -52,22 +52,17 @@ usage(void)
{ {
fprintf(stderr, "Usage: erathostenes [OPTIONS] [LIMIT]\n\n" fprintf(stderr, "Usage: erathostenes [OPTIONS] [LIMIT]\n\n"
"Options:\n" "Options:\n"
" --help Display this message.\n" " -? Display this message.\n"
" --quiet No summary line.\n" " -b SIZE Block size.\n");
" --odd-only Omit the prime 2.\n"
" --primes-only Suppress output of differences.\n"
" --diff-only Supress output of primes.\n"
" --tabular Tabular output (default is one prime per line).\n"
" --block SIZE Block size.\n");
} }
static unsigned static unsigned
isqrt(unsigned n) isqrt(unsigned long n)
{ {
unsigned x; unsigned long x;
/* FIXME: Better initialization. */ /* FIXME: Better initialization. */
if (n < UINT_MAX) if (n < ULONG_MAX)
x = n; x = n;
else else
/* Must avoid overflow in the first step. */ /* Must avoid overflow in the first step. */
...@@ -75,7 +70,7 @@ isqrt(unsigned n) ...@@ -75,7 +70,7 @@ isqrt(unsigned n)
for (;;) for (;;)
{ {
unsigned y = (x + n/x) / 2; unsigned long y = (x + n/x) / 2;
if (y >= x) if (y >= x)
return x; return x;
...@@ -85,10 +80,10 @@ isqrt(unsigned n) ...@@ -85,10 +80,10 @@ isqrt(unsigned n)
/* Size is in bits */ /* Size is in bits */
static unsigned long * static unsigned long *
vector_alloc(unsigned size) vector_alloc(unsigned long size)
{ {
unsigned end = (size + BITS_PER_LONG - 1) / BITS_PER_LONG; unsigned long end = (size + BITS_PER_LONG - 1) / BITS_PER_LONG;
unsigned i; unsigned long i;
unsigned long *vector = malloc (end * sizeof(long)); unsigned long *vector = malloc (end * sizeof(long));
if (!vector) if (!vector)
...@@ -101,13 +96,14 @@ vector_alloc(unsigned size) ...@@ -101,13 +96,14 @@ vector_alloc(unsigned size)
} }
static void static void
vector_clear_bits (unsigned long *vector, unsigned step, unsigned start, unsigned size) vector_clear_bits (unsigned long *vector, unsigned long step,
unsigned long start, unsigned long size)
{ {
unsigned bit; unsigned long bit;
for (bit = start; bit < size; bit += step) for (bit = start; bit < size; bit += step)
{ {
unsigned i = bit / BITS_PER_LONG; unsigned long i = bit / BITS_PER_LONG;
unsigned long mask = 1L << (bit % BITS_PER_LONG); unsigned long mask = 1L << (bit % BITS_PER_LONG);
vector[i] &= ~mask; vector[i] &= ~mask;
...@@ -161,11 +157,11 @@ find_first_one (unsigned long x) ...@@ -161,11 +157,11 @@ find_first_one (unsigned long x)
} }
/* Returns size if there's no more bits set */ /* Returns size if there's no more bits set */
static unsigned static unsigned long
vector_find_next (const unsigned long *vector, unsigned bit, unsigned size) vector_find_next (const unsigned long *vector, unsigned long bit, unsigned long size)
{ {
unsigned end = (size + BITS_PER_LONG - 1) / BITS_PER_LONG; unsigned long end = (size + BITS_PER_LONG - 1) / BITS_PER_LONG;
unsigned i = bit / BITS_PER_LONG; unsigned long i = bit / BITS_PER_LONG;
unsigned long mask = 1L << (bit % BITS_PER_LONG); unsigned long mask = 1L << (bit % BITS_PER_LONG);
unsigned long word; unsigned long word;
...@@ -180,125 +176,31 @@ vector_find_next (const unsigned long *vector, unsigned bit, unsigned size) ...@@ -180,125 +176,31 @@ vector_find_next (const unsigned long *vector, unsigned bit, unsigned size)
return i * BITS_PER_LONG + find_first_one(word); return i * BITS_PER_LONG + find_first_one(word);
} }
struct output_info
{
int output_2;
enum {
FORMAT_PRIMES = 1, FORMAT_DIFF = 2, FORMAT_TABULAR = 4
} format;
unsigned long last;
unsigned column;
};
static void
output_init(struct output_info *info)
{
info->output_2 = 1;
info->format = FORMAT_PRIMES | FORMAT_DIFF;
info->last = 0;
}
static void
output(struct output_info *info, unsigned long p)
{
if (info->format & (FORMAT_PRIMES | FORMAT_DIFF))
{
if (info->format & FORMAT_PRIMES)
printf("%ld", p);
if (info->format & FORMAT_DIFF)
printf(" %ld", p - info->last);
if (info->format & FORMAT_TABULAR)
{
printf(",");
info->column++;
if (info->column == 16)
{
printf("\n");
info->column = 0;
}
else
printf(" ");
}
else
printf("\n");
}
info->last = p;
}
static void
output_first(struct output_info *info)
{
info->column = 0;
if (info->output_2)
output(info, 2);
info->last = 2;
}
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
unsigned long *vector; unsigned long *vector;
/* Generate all primes p <= limit */ /* Generate all primes p <= limit */
unsigned limit; unsigned long limit;
unsigned size; unsigned long size;
unsigned bit; unsigned long bit;
unsigned prime_count; unsigned long sieve_limit;
unsigned sieve_limit; unsigned long block_size;
unsigned block_size; unsigned long block;
unsigned block;
struct output_info info;
int quiet;
int c;
enum { FLAG_ODD = -100, FLAG_PRIME, FLAG_DIFF, FLAG_TABULAR,
FLAG_QUIET, FLAG_BLOCK };
static const struct option options[] =
{
/* Name, args, flag, val */
{ "help", no_argument, NULL, '?' },
{ "quiet", no_argument, NULL, FLAG_QUIET },
{ "odd-only", no_argument, NULL, FLAG_ODD },
{ "prime-only", no_argument, NULL, FLAG_PRIME },
{ "diff-only", no_argument, NULL, FLAG_DIFF },
{ "tabular", no_argument, NULL, FLAG_TABULAR },
{ "block" , required_argument, NULL, FLAG_BLOCK },
{ NULL, 0, NULL, 0}
};
output_init(&info); int c;
quiet = 0;
block_size = 0; block_size = 0;
while ( (c = getopt_long(argc, argv, "?", options, NULL)) != -1) while ( (c = getopt(argc, argv, "?b:")) != -1)
switch (c) switch (c)
{ {
case '?': case '?':
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
case FLAG_ODD: case 'b':
info.output_2 = 0;
break;
case FLAG_PRIME:
info.format &= ~FORMAT_DIFF;
break;
case FLAG_DIFF:
info.format &= ~FORMAT_PRIMES;
break;
case FLAG_TABULAR:
info.format |= FORMAT_TABULAR;
break;
case FLAG_QUIET:
quiet = 1;
break;
case FLAG_BLOCK:
{ {
int arg = atoi(optarg); long arg = atoi(optarg);
if (arg <= 10) if (arg <= 10)
{ {
usage(); usage();
...@@ -340,8 +242,7 @@ main (int argc, char **argv) ...@@ -340,8 +242,7 @@ main (int argc, char **argv)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
output_first(&info); printf("2\n");
prime_count = 1;
bit = 0; bit = 0;
...@@ -352,10 +253,9 @@ main (int argc, char **argv) ...@@ -352,10 +253,9 @@ main (int argc, char **argv)
while (bit < sieve_limit) while (bit < sieve_limit)
{ {
unsigned n = 3 + 2 * bit; unsigned long n = 3 + 2 * bit;
output(&info, n); printf("%lu\n", n);
prime_count++;
/* First bit to clear corresponds to n^2, which is bit /* First bit to clear corresponds to n^2, which is bit
...@@ -367,18 +267,15 @@ main (int argc, char **argv) ...@@ -367,18 +267,15 @@ main (int argc, char **argv)
} }
/* No more marking, just output the remaining primes. */ /* No more marking, just output the remaining primes. */
while (bit < block_size) for (; bit < block_size ;
{ bit = vector_find_next (vector, bit + 1, size))
output(&info, 3 + 2 * bit);
prime_count++;
bit = vector_find_next (vector, bit + 1, size); printf("%lu\n", 3 + 2 * bit);
}
for (block = block_size; block < size; block += block_size) for (block = block_size; block < size; block += block_size)
{ {
unsigned block_start; unsigned long block_start;
unsigned block_end; unsigned long block_end;
if (block + block_size > size) if (block + block_size > size)
/* For the final block */ /* For the final block */
...@@ -390,12 +287,12 @@ main (int argc, char **argv) ...@@ -390,12 +287,12 @@ main (int argc, char **argv)
sieve_limit = (isqrt(block_end) - 1) / 2; sieve_limit = (isqrt(block_end) - 1) / 2;
for (bit = 0; bit < sieve_limit ;) for (bit = 0; bit < sieve_limit ;)
{ {
unsigned n = 3 + 2 * bit; unsigned long n = 3 + 2 * bit;
unsigned start = n*bit + 3*(bit + 1); unsigned long start = n*bit + 3*(bit + 1);
if (start < block) if (start < block)
{ {
unsigned k = (block + 1) / n; unsigned long k = (block + 1) / n;
start = bit + k*n; start = bit + k*n;
} }
vector_clear_bits (vector, n, start, block + block_size); vector_clear_bits (vector, n, start, block + block_size);
...@@ -405,16 +302,7 @@ main (int argc, char **argv) ...@@ -405,16 +302,7 @@ main (int argc, char **argv)
for (bit = vector_find_next (vector, block, block + block_size); for (bit = vector_find_next (vector, block, block + block_size);
bit < block + block_size; bit < block + block_size;
bit = vector_find_next (vector, bit + 1, block + block_size)) bit = vector_find_next (vector, bit + 1, block + block_size))
{ printf("%lu\n", 3 + 2 * bit);
output(&info, 3 + 2 * bit);
prime_count++;
}
}
if (!quiet)
{
printf("\n");
fprintf(stderr, "Prime #%d = %ld\n", prime_count, info.last);
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment