home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Professional
/
OS2PRO194.ISO
/
os2
/
prgramer
/
unix
/
emx
/
test
/
sieve.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-23
|
2KB
|
113 lines
/* sieve.c (emx+gcc) */
/* Define BITS to use bit encoding instead of byte encoding */
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#define FALSE 0
#define TRUE 1
#define N(x) ((x)/3)
typedef unsigned long ULONG;
typedef unsigned char BYTE;
#if defined (BITS)
#define index(c) ((c)>>3)
#define mask(c) (1<<((c)&0x07))
#define BIT_ON(map,c) (map[index(c)] & mask(c))
#define BIT_OFF(map,c) (!BIT_ON(map,c))
#define SET_TRUE(map,c) map[index(c)] |= mask(c)
#define SET_FALSE(map,c) map[index(c)] &= ~mask(c)
#define BYTES(s) (((s)+7)>>3)
#else
#define BIT_ON(map,c) map[c]
#define BIT_OFF(map,c) !map[c]
#define SET_TRUE(map,c) map[c] = 1
#define SET_FALSE(map,c) map[c] = 0
#define BYTES(s) (s)
#endif
static ULONG isqrt (ULONG x);
static void usage (void);
static ULONG isqrt (ULONG x)
{
ULONG l, r, m;
l = 1; r = x;
while (l < r)
{
m = (l+r) / 2;
if (m > 46340) m = 46340; /* avoid overflow when computing m*m */
if (m*m < x)
l = m+1;
else if (m*m > x)
r = m-1;
else
return (m);
}
return ((l+r)/2);
}
static void usage (void)
{
fputs ("Usage: sieve [-p] <number>\n", stderr);
exit (1);
}
int main (int argc, char *argv[])
{
ULONG sqrt_size, i, j, n, primes, size;
int incr, jincr, idx, print_flag;
size_t bytes;
char *p;
BYTE *bitmap;
print_flag = FALSE;
for (idx = 1; idx < argc; ++idx)
if (strcmp (argv[idx], "-p") == 0)
print_flag = TRUE;
else
break;
if (argc - idx != 1)
usage ();
errno = 0;
size = strtoul (argv[idx], &p, 10);
if (errno != 0 || *p != 0 || size < 10 || size > 2000000000)
usage ();
bytes = BYTES (N (size) + 1);
bitmap = malloc (bytes);
if (bitmap == NULL)
{
fputs ("Out of memory\n", stderr);
exit (2);
}
memset (bitmap, 0, bytes);
sqrt_size = isqrt (size);
for (i = 5, incr = 4, n = 1; i <= sqrt_size; i += (incr=6-incr), ++n)
if (BIT_OFF (bitmap, n))
for (j = i, jincr = incr; j <= size/i; j += (jincr = 6-jincr))
SET_TRUE (bitmap, N(i*j));
if (print_flag)
printf ("2 3 ");
for (i = 5, incr = 4, n = 1, primes = 2; i <= size; i += (incr=6-incr), ++n)
if (BIT_OFF (bitmap, n))
{
++primes;
if (print_flag)
printf ("%lu ", i);
}
printf ("\n%lu primes\n", primes);
return (0);
}