More than 2015 C ++ version 2 27 implementation of the lookup table for 1 GB of memory:
#include <iostream.h> // cerr, cout, and NULL #include <string.h> // memcpy() #define uint unsigned __int32 uint *factors; const uint MAX_F=134217728; // 2^27 void buildFactors(){ factors=new (nothrow) uint [(MAX_F+1)*2]; // 4 * 2 * 2^27 = 2^30 = 1GB if(factors==NULL)return; // not able to allocate enough free memory int i; for(i=0;i<(MAX_F+1)*2;i++)factors[i]=0; //Sieve of Eratosthenese factors[1*2]=1; factors[1*2+1]=1; for(i=2;i*i<=MAX_F;i++){ for(;factors[i*2] && i*i<=MAX_F;i++); factors[i*2]=1; factors[i*2+1]=i; for(int j=2;i*j<=MAX_F;j++){ factors[i*j*2]=i; factors[i*j*2+1]=j; } } for(;i<=MAX_F;i++){ for(;i<=MAX_F && factors[i*2];i++); if(i>MAX_F)return; factors[i*2]=1; factors[i*2+1]=i; } } uint * factor(uint x, int &factorCount){ if(x > MAX_F){factorCount=-1;return NULL;} uint tmp[70], at=x; int i=0; while(factors[at*2]>1){ tmp[i++]=factors[at*2]; cout<<"at:"<<at<<" tmp:"<<tmp[i-1]<<endl; at=factors[at*2+1]; } if(i==0){ cout<<"at:"<<x<<" tmp:1"<<endl; tmp[i++]=1; tmp[i++]=x; }else{ cout<<"at:"<<at<<" tmp:1"<<endl; tmp[i++]=at; } factorCount=i; uint *ret=new (nothrow) uint [factorCount]; if(ret!=NULL) memcpy(ret, tmp, sizeof(uint)*factorCount); return ret; } void main(){ cout<<"Loading factors lookup table"<<endl; buildFactors(); if(factors==NULL){cerr<<"Need 1GB block of free memory"<<endl;return;} int size; uint x=30030; cout<<"\nFactoring: "<<x<<endl; uint *f=factor(x,size); if(size<0){cerr<<x<<" is too big to factor. Choose a number between 1 and "<<MAX_F<<endl;return;} else if(f==NULL){cerr<<"ran out of memory trying to factor "<<x<<endl;return;} cout<<"\nThe factors of: "<<x<<" {"<<f[0]; for(int i=1;i<size;i++) cout<<", "<<f[i]; cout<<"}"<<endl; delete [] f; x=30637; cout<<"\nFactoring: "<<x<<endl; f=factor(x,size); cout<<"\nThe factors of: "<<x<<" {"<<f[0]; for(int i=1;i<size;i++) cout<<", "<<f[i]; cout<<"}"<<endl; delete [] f; delete [] factors; }
Update: or sacrifice some simplicity for a slightly larger range in just 2 28
#include <iostream.h> // cerr, cout, and NULL #include <string.h> // memcpy(), memset() //#define dbg(A) A #ifndef dbg #define dbg(A) #endif #define uint unsigned __int32 #define uint8 unsigned __int8 #define uint16 unsigned __int16 uint * factors; uint8 *factors08; uint16 *factors16; uint *factors32; const uint LIMIT_16 = 514; // First 16-bit factor, 514 = 2*257 const uint LIMIT_32 = 131074;// First 32-bit factor, 131074 = 2*65537 const uint MAX_FACTOR = 268501119; //const uint64 LIMIT_64 = 8,589,934,594; // First 64-bit factor, 2^33+1 const uint TABLE_SIZE = 268435456; // 2^28 => 4 * 2^28 = 2^30 = 1GB 32-bit table const uint o08=1, o16=257 ,o32=65665; //o64=4294934465 // TableSize = 2^37 => 8 * 2^37 = 2^40 1TB 64-bit table // => MaxFactor = 141,733,953,600 /* Layout of factors[] array * Indicies(32-bit) i Value Size AFactorOf(i) * ---------------- ------ ---------- ---------------- * factors[0..128] [1..513] 8-bit factors08[i-o08] * factors[129..65408] [514..131073] 16-bit factors16[i-o16] * factors[65409..268435455] [131074..268501119] 32-bit factors32[i-o32] * * Note: stopping at i*i causes AFactorOf(i) to not always be LargestFactor(i) */ void buildFactors(){ dbg(cout<<"Allocating RAM"<<endl;) factors=new (nothrow) uint [TABLE_SIZE]; // 4 * 2^28 = 2^30 = 1GB if(factors==NULL)return; // not able to allocate enough free memory uint i,j; factors08 = (uint8 *)factors; factors16 = (uint16 *)factors; factors32 = factors; dbg(cout<<"Zeroing RAM"<<endl;) memset(factors,0,sizeof(uint)*TABLE_SIZE); //for(i=0;i<TABLE_SIZE;i++)factors[i]=0; //Sieve of Eratosthenese //8-bit values dbg(cout<<"Setting: 8-Bit Values"<<endl;) factors08[1-o08]=1; for(i=2;i*i<LIMIT_16;i++){ for(;factors08[i-o08] && i*i<LIMIT_16;i++); dbg(cout<<"Filtering: "<<i<<endl;) factors08[i-o08]=1; for(j=2;i*j<LIMIT_16;j++)factors08[i*j-o08]=i; for(;i*j<LIMIT_32;j++)factors16[i*j-o16]=i; for(;i*j<=MAX_FACTOR;j++)factors32[i*j-o32]=i; } for(;i<LIMIT_16;i++){ for(;i<LIMIT_16 && factors08[i-o08];i++); dbg(cout<<"Filtering: "<<i<<endl;) if(i<LIMIT_16){ factors08[i-o08]=1; j=LIMIT_16/i+(LIMIT_16%i>0); for(;i*j<LIMIT_32;j++)factors16[i*j-o16]=i; for(;i*j<=MAX_FACTOR;j++)factors32[i*j-o32]=i; } }i--; dbg(cout<<"Setting: 16-Bit Values"<<endl;) //16-bit values for(;i*i<LIMIT_32;i++){ for(;factors16[i-o16] && i*i<LIMIT_32;i++); factors16[i-o16]=1; for(j=2;i*j<LIMIT_32;j++)factors16[i*j-o16]=i; for(;i*j<=MAX_FACTOR;j++)factors32[i*j-o32]=i; } for(;i<LIMIT_32;i++){ for(;i<LIMIT_32 && factors16[i-o16];i++); if(i<LIMIT_32){ factors16[i-o16]=1; j=LIMIT_32/i+(LIMIT_32%i>0); for(;i*j<=MAX_FACTOR;j++)factors32[i*j-o32]=i; } }i--; dbg(cout<<"Setting: 32-Bit Values"<<endl;) //32-bit values for(;i*i<=MAX_FACTOR;i++){ for(;factors32[i-o32] && i*i<=MAX_FACTOR;i++); factors32[i-o32]=1; for(j=2;i*j<=MAX_FACTOR;j++)factors32[i*j-o32]=i; } for(;i<=MAX_FACTOR;i++){ for(;i<=MAX_FACTOR && factors32[i-o32];i++); if(i>MAX_FACTOR)return; factors32[i-o32]=1; } } uint * factor(uint x, int &factorCount){ if(x > MAX_FACTOR){factorCount=-1;return NULL;} uint tmp[70], at=x; int i=0; while(at>=LIMIT_32 && factors32[at-o32]>1){ tmp[i++]=factors32[at-o32]; dbg(cout<<"at32:"<<at<<" tmp:"<<tmp[i-1]<<endl;) at/=tmp[i-1]; } if(at<LIMIT_32){ while(at>=LIMIT_16 && factors16[at-o16]>1){ tmp[i++]=factors16[at-o16]; dbg(cout<<"at16:"<<at<<" tmp:"<<tmp[i-1]<<endl;) at/=tmp[i-1]; } if(at<LIMIT_16){ while(factors08[at-o08]>1){ tmp[i++]=factors08[at-o08]; dbg(cout<<"at08:"<<at<<" tmp:"<<tmp[i-1]<<endl;) at/=tmp[i-1]; } } } if(i==0){ dbg(cout<<"at:"<<x<<" tmp:1"<<endl;) tmp[i++]=1; tmp[i++]=x; }else{ dbg(cout<<"at:"<<at<<" tmp:1"<<endl;) tmp[i++]=at; } factorCount=i; uint *ret=new (nothrow) uint [factorCount]; if(ret!=NULL) memcpy(ret, tmp, sizeof(uint)*factorCount); return ret; } uint AFactorOf(uint x){ if(x > MAX_FACTOR)return -1; if(x < LIMIT_16) return factors08[x-o08]; if(x < LIMIT_32) return factors16[x-o16]; return factors32[x-o32]; } void main(){ cout<<"Loading factors lookup table"<<endl; buildFactors(); if(factors==NULL){cerr<<"Need 1GB block of free memory"<<endl;return;} int size; uint x=13855127;//25255230;//30030; cout<<"\nFactoring: "<<x<<endl; uint *f=factor(x,size); if(size<0){cerr<<x<<" is too big to factor. Choose a number between 1 and "<<MAX_FACTOR<<endl;return;} else if(f==NULL){cerr<<"ran out of memory trying to factor "<<x<<endl;return;} cout<<"\nThe factors of: "<<x<<" {"<<f[0]; for(int i=1;i<size;i++) cout<<", "<<f[i]; cout<<"}"<<endl; delete [] f; x=30637; cout<<"\nFactoring: "<<x<<endl; f=factor(x,size); cout<<"\nThe factors of: "<<x<<" {"<<f[0]; for(int i=1;i<size;i++) cout<<", "<<f[i]; cout<<"}"<<endl; delete [] f; delete [] factors; }
Gregor y Oct 26 '15 at 21:24 2015-10-26 21:24
source share