/********************************************* * * Copyright 2004 by Sean Conner. All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Comments, questions and criticisms can be sent to: sean@conman.org * **********************************************/ #include #include #include #include #include /************************************************************************* * * This is the number of bytes to set aside to hold the result. The number * of digits of the final result will be approximately 2.3 times this number. * ************************************************************************/ #define E (24*1024) /************************************************************************ * * Various constants used in the program * *************************************************************************/ #define LOGPI2div2 (double)0.399089934 #define LN10 (double)2.302585093 #define LOG256 (double)2.408239965 #ifndef FALSE # define FALSE 0 #endif #ifndef TRUE # define TRUE !FALSE #endif /************************************************************************/ unsigned char *e; unsigned long esize = E; /***********************************************************************/ int main (int,char *[]); static void calc_e (unsigned short); static void div_e (unsigned short); static double num_digits (unsigned long); static unsigned long calc_n (double); static void print_e (double); static unsigned short e10 (void); /************************************************************************/ int main(int argc,char *argv[]) { unsigned long n; double nd; if (argc > 1) { esize = strtol(argv[1],NULL,10); } nd = num_digits(esize); n = calc_n(nd); printf("bytes: %lu nd: %f mag: 10**%lu\n",esize,nd,n); if (n == 0) { fprintf(stderr,"Can not calculate\n"); return(1); } e = malloc(esize * sizeof(unsigned char)); if (e == NULL) { fprintf(stderr,"no memory\n"); return(1); } calc_e(n); print_e(nd); return(0); } /**********************************************************************/ static void calc_e(unsigned short nmax) { unsigned short n; for (n = nmax ; n > 1 ; n--) { div_e(n); } } /***********************************************************************/ #define inline() { \ ter += ter; \ te += te; \ a += a; \ if (te & 0x0100) a |= 0x0001; \ if (a >= n) \ { \ a -= n; \ ter |= 0x01; \ } \ } static void div_e(unsigned short n) { unsigned short a; unsigned short te; unsigned char ter; int i; a = 1; for (i = 0 ; i < esize ; i++) { ter = 0; te = e[i]; inline(); inline(); inline(); inline(); inline(); inline(); inline(); inline(); e[i] = ter; } } /*******************************************************************/ static double num_digits(unsigned long e) { return((double)e * LOG256); } /************************************************************************/ static unsigned long calc_n(double digits) { unsigned long i; double n; double magnb; for(i = 1 , n = 1.0 ; i < ULONG_MAX ; i++ , n+= 1.0) { magnb = LOGPI2div2 + (log10(n) * (n + 0.5)) - ( n / LN10) ; if (magnb > digits) { return(i); } } return(0); } /************************************************************************* * * The print module * *************************************************************************/ static void print_e(double nd) { int page = 0; int group = 0; int digit = 0; int even = TRUE; unsigned short p; for ( ; nd > 0 ; nd -= 1.0) { if (digit == 5) { putchar(' '); digit = 0; group++; } if (group == 12) { putchar('\n'); group = 0; page++; } if (page == 60) { putchar('\n'); putchar('\n'); page = 0; } digit++; if (even) { p = e10(); putchar((p/10) + '0'); even = FALSE; } else { putchar((p % 10) + '0'); even = TRUE; } } putchar('\n'); } /**********************************************************************/ static unsigned short e10(void) { unsigned short p; int i; unsigned char c; c = 0; for (i = esize-1 ; i >= 0 ; i--) { p = (e[i] * 100) + c; e[i] = p & 0xff; c = (p >> 8) & 0xff; } p = c; return(p); } /*************************************************************************/