Prime number table

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <math.h>

int  main(int argc, char **argv)
{
    long long start = atoll(argv[1]);
    long long end = atoll(argv[2]);

    // make start even
    start -= start&1;
    printf("start = %015lld end=%015lld ",start, end);

    long long lsize = end-start +1;
    // make sure size is 4 bytes
    if(lsize > 0xffffffff)
    {
	printf("size %lld too large, %f times max\n", lsize, lsize*1.0/0xffffffff);
	exit(1);
    }
    unsigned int size = lsize;

    // large prime flags
    char *pflag=(char *)malloc(size);
    int i;
    for(i=0;i<size;i++) pflag[i]=i&1;

    int divmax = (int)(sqrt(end*1.0))-1;
    while((long long)divmax*divmax < end) divmax++;
    printf("#dmax=%d\n",divmax);

    //small prime flags
    char *pflag2=(char *)malloc(divmax);
    for(i=0;i<divmax;i++) pflag2[i]=i&1;

    int div=3;
    while(div < divmax)
    {
	for(i=div;i<=divmax;i+=div) pflag2[i-2]=0;

	int mod = start % div;
	int istart = 0;
	if(mod != 0) istart = div - mod;
        if(start + istart<=div) istart+=div;
	//even
	if((istart&1)==0) istart+=div;
	//nuke
	for(i=istart; i<size;i += div*2) pflag[i]=0;

	// find next prime
	while((div-2 < divmax) && pflag2[div-2]==0 )div++;
	printf("Prog %f %d\n",div*100.0/divmax, div);
    }

    // count
    int nprime=0;

    for(i=0;i<size;i++) 
    {
	nprime += pflag[i];
    }
#define TABSIZE 256
    int ntable = nprime/TABSIZE;
    if (ntable * TABSIZE < nprime) ntable++;

    // prime table
    unsigned int *ptable = (unsigned int *)malloc(sizeof(int)* nprime);

    int n=0;
    for(i=0;i<size;i++) 
    {
	if(pflag[i]==1)
	{
	    ptable[n]=i;
	    n++;
	}
    }
    // max separation 
    int nsep8=0, nsep16=0;
    char *bperdat = (char *)malloc(ntable);
    long long *pstab = (long long *)malloc(ntable*sizeof(long long));
    int sepdata[TABSIZE];

    int t;
    for(t=0;t<ntable;t++)
    {
	int pstart=t*TABSIZE;
	int pend = pstart+TABSIZE;
	if(pend>nprime)pend=nprime;
	pstab[t] = ptable[pstart];

	int sepmax=0;
	for(i=pstart+1;i<pend;i++)
	{
	    // separation is always even
	    int sep = (ptable[i] - ptable[i-1])/2;
	    if(sep>sepmax)sepmax=sep;
	}
	if(sepmax >255)
	{
	    nsep16++;
	    bperdat[t]=2;
	}
	else
	{
	    nsep8++;
	    bperdat[t]=1;
	}
    }//t

    printf("# bytes per data  8=%d, 16=%d\n", nsep8, nsep16);

    char fn[512];
    sprintf(fn, "ptable%015lld",start);
    FILE *fp=fopen(fn, "w");

    int fofs = 0;
    // number of primes
    fwrite(&nprime,1,4,fp);
    fofs+=4;
    // number of tables
    fwrite(&ntable,1,4,fp);
    fofs+=4;
    // table size
    int ts = TABSIZE;
    fwrite(&ts,1,4,fp);
    fofs+=4;
    //start value of each table
    fwrite(pstab, sizeof(long long), ntable, fp);
    fofs+= ntable * sizeof(long long);
    // table bytes per data
    fwrite(bperdat, 1, ntable, fp);
    fofs += ntable;

    // prepare fseek offset table
    int *ofstab = (int *)malloc(ntable * sizeof(int));
    fofs += ntable * 4;
    for(t=0;t<ntable;t++)
    {
	ofstab[t] = fofs;
	fofs += bperdat[t]*(TABSIZE-1);
    }
    fwrite(ofstab, 4, ntable, fp);

    unsigned short stab16[TABSIZE-1];
    unsigned char stab8[TABSIZE-1];
    for(t=0;t<ntable;t++)
    {
	int bpd = bperdat[t];
	int pstart=t*TABSIZE;
	int pend = pstart+TABSIZE;
	if(pend>nprime)pend=nprime;
	int ix=0;
	for(i=pstart+1;i<pend;i++)
	{
	    // separation is always even
	    int sep = (ptable[i] - ptable[i-1])/2;
	    stab8[ix]=sep;
	    stab16[ix]=sep;
	    ix++;
	}
	if(bpd==1)
	    fwrite(stab8, 1, TABSIZE-1,fp); 
	else
	    fwrite(stab16, 2, TABSIZE-1,fp); 
    }//t
    fclose(fp);

    free(pflag);
    free(pflag2);
    free(ptable);
    free(bperdat);
    free(pstab);
}