[BACK]Return to pexpr.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / demos

Diff for /OpenXM_contrib/gmp/demos/Attic/pexpr.c between version 1.1 and 1.1.1.2

version 1.1, 2000/09/09 14:13:19 version 1.1.1.2, 2003/08/25 16:06:03
Line 1 
Line 1 
 /* Program for computing integer expressions using the GNU Multiple Precision  /* Program for computing integer expressions using the GNU Multiple Precision
    Arithmetic Library.     Arithmetic Library.
   
 Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.  Copyright 1997, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
   
 This program is free software; you can redistribute it and/or modify it under  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  the terms of the GNU General Public License as published by the Free Software
Line 30  Place - Suite 330, Boston, MA 02111-1307, USA.  */
Line 30  Place - Suite 330, Boston, MA 02111-1307, USA.  */
    -o        print output in octal     -o        print output in octal
    -d        print output in decimal (the default)     -d        print output in decimal (the default)
    -x        print output in hexadecimal     -x        print output in hexadecimal
    -<NUM>    print output in base NUM     -b<NUM>   print output in base NUM
    -t        print timing information     -t        print timing information
    -html     output html     -html     output html
      -wml      output wml
    -nosplit  do not split long lines each 60th digit     -nosplit  do not split long lines each 60th digit
 */  */
   
Line 40  Place - Suite 330, Boston, MA 02111-1307, USA.  */
Line 41  Place - Suite 330, Boston, MA 02111-1307, USA.  */
    use up extensive resources (cpu, memory).  Useful for the GMP demo on the     use up extensive resources (cpu, memory).  Useful for the GMP demo on the
    GMP web site, since we cannot load the server too much.  */     GMP web site, since we cannot load the server too much.  */
   
 #ifdef LIMIT_RESOURCE_USAGE  #include "pexpr-config.h"
 #include <sys/types.h>  
 #include <sys/time.h>  
 #include <sys/resource.h>  
 #endif  
   
 #include <string.h>  #include <string.h>
 #include <stdio.h>  #include <stdio.h>
Line 53  Place - Suite 330, Boston, MA 02111-1307, USA.  */
Line 50  Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include <signal.h>  #include <signal.h>
 #include <ctype.h>  #include <ctype.h>
   
   #include <time.h>
   #include <sys/types.h>
   #include <sys/time.h>
   #if HAVE_SYS_RESOURCE_H
   #include <sys/resource.h>
   #endif
   
 #include "gmp.h"  #include "gmp.h"
   
   /* SunOS 4 and HPUX 9 don't define a canonical SIGSTKSZ, use a default. */
   #ifndef SIGSTKSZ
   #define SIGSTKSZ  4096
   #endif
   
   
   #define TIME(t,func)                                                    \
     do { int __t0, __times, __t, __tmp;                                   \
       __times = 1;                                                        \
       __t0 = cputime ();                                                  \
       {func;}                                                             \
       __tmp = cputime () - __t0;                                          \
       while (__tmp < 100)                                                 \
         {                                                                 \
           __times <<= 1;                                                  \
           __t0 = cputime ();                                              \
           for (__t = 0; __t < __times; __t++)                             \
             {func;}                                                       \
           __tmp = cputime () - __t0;                                      \
         }                                                                 \
       (t) = (double) __tmp / __times;                                     \
     } while (0)
   
 /* GMP version 1.x compatibility.  */  /* GMP version 1.x compatibility.  */
 #if ! (__GNU_MP_VERSION >= 2)  #if ! (__GNU_MP_VERSION >= 2)
 typedef MP_INT __mpz_struct;  typedef MP_INT __mpz_struct;
Line 76  jmp_buf errjmpbuf;
Line 103  jmp_buf errjmpbuf;
   
 enum op_t {NOP, LIT, NEG, NOT, PLUS, MINUS, MULT, DIV, MOD, REM, INVMOD, POW,  enum op_t {NOP, LIT, NEG, NOT, PLUS, MINUS, MULT, DIV, MOD, REM, INVMOD, POW,
            AND, IOR, XOR, SLL, SRA, POPCNT, HAMDIST, GCD, LCM, SQRT, ROOT, FAC,             AND, IOR, XOR, SLL, SRA, POPCNT, HAMDIST, GCD, LCM, SQRT, ROOT, FAC,
            LOG, LOG2, FERMAT, MERSENNE, FIBONACCI};             LOG, LOG2, FERMAT, MERSENNE, FIBONACCI, RANDOM, NEXTPRIME, BINOM};
   
 /* Type for the expression tree.  */  /* Type for the expression tree.  */
 struct expr  struct expr
Line 91  struct expr
Line 118  struct expr
   
 typedef struct expr *expr_t;  typedef struct expr *expr_t;
   
 void cleanup_and_exit (int);  void cleanup_and_exit __GMP_PROTO ((int));
   
 char *skipspace (char *);  char *skipspace __GMP_PROTO ((char *));
 void makeexp (expr_t *, enum op_t, expr_t, expr_t);  void makeexp __GMP_PROTO ((expr_t *, enum op_t, expr_t, expr_t));
 void free_expr (expr_t);  void free_expr __GMP_PROTO ((expr_t));
 char *expr (char *, expr_t *);  char *expr __GMP_PROTO ((char *, expr_t *));
 char *term (char *, expr_t *);  char *term __GMP_PROTO ((char *, expr_t *));
 char *power (char *, expr_t *);  char *power __GMP_PROTO ((char *, expr_t *));
 char *factor (char *, expr_t *);  char *factor __GMP_PROTO ((char *, expr_t *));
 int match (char *, char *);  int match __GMP_PROTO ((char *, char *));
 int matchp (char *, char *);  int matchp __GMP_PROTO ((char *, char *));
 int cputime (void);  int cputime __GMP_PROTO ((void));
   
 void mpz_eval_expr (mpz_ptr, expr_t);  void mpz_eval_expr __GMP_PROTO ((mpz_ptr, expr_t));
 void mpz_eval_mod_expr (mpz_ptr, expr_t, mpz_ptr);  void mpz_eval_mod_expr __GMP_PROTO ((mpz_ptr, expr_t, mpz_ptr));
   
 char *error;  char *error;
 int flag_print = 1;  int flag_print = 1;
 int print_timing = 0;  int print_timing = 0;
 int flag_html = 0;  int flag_html = 0;
   int flag_wml = 0;
 int flag_splitup_output = 0;  int flag_splitup_output = 0;
 char *newline = "";  char *newline = "";
   gmp_randstate_t rstate;
   
 #ifdef _AIX  
 #define sigaltstack sigstack  
   /* cputime() returns user CPU time measured in milliseconds.  */
   #if ! HAVE_CPUTIME
   #if HAVE_GETRUSAGE
   int
   cputime (void)
   {
     struct rusage rus;
   
     getrusage (0, &rus);
     return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
   }
   #else
   #if HAVE_CLOCK
   int
   cputime (void)
   {
     if (CLOCKS_PER_SEC < 100000)
       return clock () * 1000 / CLOCKS_PER_SEC;
     return clock () / (CLOCKS_PER_SEC / 1000);
   }
   #else
   int
   cputime (void)
   {
     return 0;
   }
 #endif  #endif
   #endif
   #endif
   
 #if !defined(_WIN32) && !defined(__DJGPP__)  
   int
   stack_downwards_helper (char *xp)
   {
     char  y;
     return &y < xp;
   }
   int
   stack_downwards_p (void)
   {
     char  x;
     return stack_downwards_helper (&x);
   }
   
   
 void  void
 setup_error_handler ()  setup_error_handler (void)
 {  {
   #if HAVE_SIGACTION
   struct sigaction act;    struct sigaction act;
   struct sigaltstack sigstk;    act.sa_handler = cleanup_and_exit;
     sigemptyset (&(act.sa_mask));
   #define SIGNAL(sig)  sigaction (sig, &act, NULL)
   #else
     struct { int sa_flags } act;
   #define SIGNAL(sig)  signal (sig, cleanup_and_exit)
   #endif
     act.sa_flags = 0;
   
   /* Set up a stack for signal handling.  A typical cause of error is stack    /* Set up a stack for signal handling.  A typical cause of error is stack
      overflow, and in such situation a signal can not be delivered on the       overflow, and in such situation a signal can not be delivered on the
      overflown stack.  */       overflown stack.  */
   sigstk.ss_sp = malloc (SIGSTKSZ);  #if HAVE_SIGALTSTACK
 #ifndef _AIX    {
   sigstk.ss_size = SIGSTKSZ;      /* AIX uses stack_t, MacOS uses struct sigaltstack, various other
   sigstk.ss_flags = 0;         systems have both. */
 #endif /* ! _AIX */  #if HAVE_STACK_T
       stack_t s;
 #ifndef _UNICOS  #else
   if (sigaltstack (&sigstk, 0) < 0)      struct sigaltstack s;
     perror("sigaltstack");  
 #endif  #endif
       s.ss_sp = malloc (SIGSTKSZ);
       s.ss_size = SIGSTKSZ;
       s.ss_flags = 0;
       if (sigaltstack (&s, NULL) != 0)
         perror("sigaltstack");
       act.sa_flags = SA_ONSTACK;
     }
   #else
   #if HAVE_SIGSTACK
     {
       struct sigstack s;
       s.ss_sp = malloc (SIGSTKSZ);
       if (stack_downwards_p ())
         s.ss_sp += SIGSTKSZ;
       s.ss_onstack = 0;
       if (sigstack (&s, NULL) != 0)
         perror("sigstack");
       act.sa_flags = SA_ONSTACK;
     }
   #else
   #endif
   #endif
   
   /* Initialize structure for sigaction (called below).  */  
   act.sa_handler = cleanup_and_exit;  
   sigemptyset (&(act.sa_mask));  
   act.sa_flags = SA_ONSTACK;  
   
 #ifdef LIMIT_RESOURCE_USAGE  #ifdef LIMIT_RESOURCE_USAGE
   {    {
     struct rlimit limit;      struct rlimit limit;
Line 155  setup_error_handler ()
Line 250  setup_error_handler ()
     limit.rlim_max = 4;      limit.rlim_max = 4;
     setrlimit (RLIMIT_CPU, &limit);      setrlimit (RLIMIT_CPU, &limit);
   
     limit.rlim_cur = limit.rlim_max = 4 * 1024 * 1024;      limit.rlim_cur = limit.rlim_max = 16 * 1024 * 1024;
     setrlimit (RLIMIT_DATA, &limit);      setrlimit (RLIMIT_DATA, &limit);
   
     getrlimit (RLIMIT_STACK, &limit);      getrlimit (RLIMIT_STACK, &limit);
     limit.rlim_cur = 1 * 1024 * 1024;      limit.rlim_cur = 4 * 1024 * 1024;
     setrlimit (RLIMIT_STACK, &limit);      setrlimit (RLIMIT_STACK, &limit);
   
     sigaction (SIGXCPU, &act, 0);      SIGNAL (SIGXCPU);
   }    }
 #endif /* LIMIT_RESOURCE_USAGE */  #endif /* LIMIT_RESOURCE_USAGE */
   
   sigaction (SIGILL, &act, 0);    SIGNAL (SIGILL);
   sigaction (SIGSEGV, &act, 0);    SIGNAL (SIGSEGV);
   sigaction (SIGBUS, &act, 0);  #ifdef SIGBUS /* not in mingw */
   sigaction (SIGFPE, &act, 0);    SIGNAL (SIGBUS);
   #endif
     SIGNAL (SIGFPE);
     SIGNAL (SIGABRT);
 }  }
 #endif /* ! _WIN32 && ! __DJGPP__ */  
   
   int
 main (int argc, char **argv)  main (int argc, char **argv)
 {  {
   struct expr *e;    struct expr *e;
Line 182  main (int argc, char **argv)
Line 280  main (int argc, char **argv)
   char *str;    char *str;
   int base = 10;    int base = 10;
   
 #if !defined(_WIN32) && !defined(__DJGPP__)  
   setup_error_handler ();    setup_error_handler ();
   
     gmp_randinit (rstate, GMP_RAND_ALG_LC, 128);
   
     {
   #if HAVE_GETTIMEOFDAY
       struct timeval tv;
       gettimeofday (&tv, NULL);
       gmp_randseed_ui (rstate, tv.tv_sec + tv.tv_usec);
   #else
       time_t t;
       time (&t);
       gmp_randseed_ui (rstate, t);
 #endif  #endif
     }
   
   mpz_init (r);    mpz_init (r);
   
Line 210  main (int argc, char **argv)
Line 320  main (int argc, char **argv)
         base = 2;          base = 2;
       else if (arg[1] == 'x' && arg[2] == 0)        else if (arg[1] == 'x' && arg[2] == 0)
         base = 16;          base = 16;
         else if (arg[1] == 'X' && arg[2] == 0)
           base = -16;
       else if (arg[1] == 'o' && arg[2] == 0)        else if (arg[1] == 'o' && arg[2] == 0)
         base = 8;          base = 8;
       else if (arg[1] == 'd' && arg[2] == 0)        else if (arg[1] == 'd' && arg[2] == 0)
Line 217  main (int argc, char **argv)
Line 329  main (int argc, char **argv)
       else if (strcmp (arg, "-html") == 0)        else if (strcmp (arg, "-html") == 0)
         {          {
           flag_html = 1;            flag_html = 1;
           newline = "<BR>";            newline = "<br>";
         }          }
         else if (strcmp (arg, "-wml") == 0)
           {
             flag_wml = 1;
             newline = "<br/>";
           }
       else if (strcmp (arg, "-split") == 0)        else if (strcmp (arg, "-split") == 0)
         {          {
           flag_splitup_output = 1;            flag_splitup_output = 1;
Line 303  main (int argc, char **argv)
Line 420  main (int argc, char **argv)
           continue;            continue;
         }          }
   
       {        if (print_timing)
         int t0;          {
             double t;
         if (print_timing)            TIME (t, mpz_eval_expr (r, e));
           t0 = cputime ();            printf ("computation took %.2f ms%s\n", t, newline);
           }
         else
         mpz_eval_expr (r, e);          mpz_eval_expr (r, e);
   
         if (print_timing)  
           printf ("computation took %d ms%s\n", cputime () - t0, newline);  
       }  
   
       if (flag_print)        if (flag_print)
         {          {
           size_t out_len;            size_t out_len;
           char *tmp, *s;            char *tmp, *s;
           int t0;  
   
           out_len = mpz_sizeinbase (r, base) + 1;            out_len = mpz_sizeinbase (r, base >= 0 ? base : -base) + 2;
           tmp = malloc (out_len);            tmp = malloc (out_len);
   
           if (print_timing)            if (print_timing)
             t0 = cputime ();              {
                 double t;
                 printf ("output conversion ");
                 TIME (t, mpz_get_str (tmp, base, r));
                 printf ("took %.2f ms%s\n", t, newline);
               }
             else
               mpz_get_str (tmp, base, r);
   
           if (print_timing)  
             /* Print first half of message... */  
             printf ("output conversion ");  
   
           mpz_get_str (tmp, -base, r);  
   
           if (print_timing)  
             /* ...print 2nd half of message unless we caught a time limit  
                and therefore longjmp'ed */  
             printf ("took %d ms%s\n", cputime () - t0, newline);  
   
           out_len = strlen (tmp);            out_len = strlen (tmp);
           if (flag_splitup_output)            if (flag_splitup_output)
             {              {
Line 584  struct functions fns[] =
Line 693  struct functions fns[] =
 #if __GNU_MP_VERSION >= 2  #if __GNU_MP_VERSION >= 2
   {"root", ROOT, 2},    {"root", ROOT, 2},
   {"popc", POPCNT, 1},    {"popc", POPCNT, 1},
     {"hamdist", HAMDIST, 2},
 #endif  #endif
   {"gcd", GCD, 0},    {"gcd", GCD, 0},
 #if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1  #if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
Line 595  struct functions fns[] =
Line 705  struct functions fns[] =
   {"xor", XOR, 0},    {"xor", XOR, 0},
 #endif  #endif
   {"plus", PLUS, 0},    {"plus", PLUS, 0},
     {"pow", POW, 2},
   {"minus", MINUS, 2},    {"minus", MINUS, 2},
   {"mul", MULT, 0},    {"mul", MULT, 0},
   {"div", DIV, 2},    {"div", DIV, 2},
Line 609  struct functions fns[] =
Line 720  struct functions fns[] =
   {"M", MERSENNE, 1},    {"M", MERSENNE, 1},
   {"fib", FIBONACCI, 1},    {"fib", FIBONACCI, 1},
   {"Fib", FIBONACCI, 1},    {"Fib", FIBONACCI, 1},
     {"random", RANDOM, 1},
     {"nextprime", NEXTPRIME, 1},
     {"binom", BINOM, 2},
     {"binomial", BINOM, 2},
   {"", NOP, 0}    {"", NOP, 0}
 };  };
   
Line 849  mpz_eval_expr (mpz_ptr r, expr_t e)
Line 964  mpz_eval_expr (mpz_ptr r, expr_t e)
     case POW:      case POW:
       mpz_init (lhs); mpz_init (rhs);        mpz_init (lhs); mpz_init (rhs);
       mpz_eval_expr (lhs, e->operands.ops.lhs);        mpz_eval_expr (lhs, e->operands.ops.lhs);
         if (mpz_cmpabs_ui (lhs, 1) <= 0)
           {
             /* For 0^rhs and 1^rhs, we just need to verify that
                rhs is well-defined.  For (-1)^rhs we need to
                determine (rhs mod 2).  For simplicity, compute
                (rhs mod 2) for all three cases.  */
             expr_t two, et;
             two = malloc (sizeof (struct expr));
             two -> op = LIT;
             mpz_init_set_ui (two->operands.val, 2L);
             makeexp (&et, MOD, e->operands.ops.rhs, two);
             e->operands.ops.rhs = et;
           }
   
       mpz_eval_expr (rhs, e->operands.ops.rhs);        mpz_eval_expr (rhs, e->operands.ops.rhs);
       if (mpz_cmp_si (rhs, 0L) == 0)        if (mpz_cmp_si (rhs, 0L) == 0)
         /* x^0 is 1 */          /* x^0 is 1 */
Line 999  mpz_eval_expr (mpz_ptr r, expr_t e)
Line 1128  mpz_eval_expr (mpz_ptr r, expr_t e)
 #if __GNU_MP_VERSION >= 2  #if __GNU_MP_VERSION >= 2
     case POPCNT:      case POPCNT:
       mpz_eval_expr (r, e->operands.ops.lhs);        mpz_eval_expr (r, e->operands.ops.lhs);
       { unsigned long int cnt;        { long int cnt;
         cnt = mpz_popcount (r);          cnt = mpz_popcount (r);
         mpz_set_ui (r, cnt);          mpz_set_si (r, cnt);
       }        }
       return;        return;
       case HAMDIST:
         { long int cnt;
           mpz_init (lhs); mpz_init (rhs);
           mpz_eval_expr (lhs, e->operands.ops.lhs);
           mpz_eval_expr (rhs, e->operands.ops.rhs);
           cnt = mpz_hamdist (lhs, rhs);
           mpz_clear (lhs); mpz_clear (rhs);
           mpz_set_si (r, cnt);
         }
         return;
 #endif  #endif
     case LOG2:      case LOG2:
       mpz_eval_expr (r, e->operands.ops.lhs);        mpz_eval_expr (r, e->operands.ops.lhs);
Line 1105  mpz_eval_expr (mpz_ptr r, expr_t e)
Line 1244  mpz_eval_expr (mpz_ptr r, expr_t e)
 #endif  #endif
       }        }
       return;        return;
       case RANDOM:
         {
           unsigned long int n;
           mpz_init (lhs);
           mpz_eval_expr (lhs, e->operands.ops.lhs);
           if (mpz_sgn (lhs) <= 0 || mpz_cmp_si (lhs, 1000000000) > 0)
             {
               error = "random number size out of range";
               mpz_clear (lhs);
               longjmp (errjmpbuf, 1);
             }
           n = mpz_get_ui (lhs);
           mpz_clear (lhs);
           mpz_urandomb (r, rstate, n);
         }
         return;
       case NEXTPRIME:
         {
           mpz_eval_expr (r, e->operands.ops.lhs);
           mpz_nextprime (r, r);
         }
         return;
       case BINOM:
         mpz_init (lhs); mpz_init (rhs);
         mpz_eval_expr (lhs, e->operands.ops.lhs);
         mpz_eval_expr (rhs, e->operands.ops.rhs);
         {
           unsigned long int k;
           if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
             {
               error = "k too large in (n over k) expression";
               mpz_clear (lhs); mpz_clear (rhs);
               longjmp (errjmpbuf, 1);
             }
           k = mpz_get_ui (rhs);
           mpz_bin_ui (r, lhs, k);
         }
         mpz_clear (lhs); mpz_clear (rhs);
         return;
     default:      default:
       abort ();        abort ();
     }      }
Line 1167  mpz_eval_mod_expr (mpz_ptr r, expr_t e, mpz_ptr mod)
Line 1345  mpz_eval_mod_expr (mpz_ptr r, expr_t e, mpz_ptr mod)
 void  void
 cleanup_and_exit (int sig)  cleanup_and_exit (int sig)
 {  {
     switch (sig) {
 #ifdef LIMIT_RESOURCE_USAGE  #ifdef LIMIT_RESOURCE_USAGE
   if (sig == SIGXCPU)    case SIGXCPU:
     printf ("expression took too long time to evaluate%s\n", newline);      printf ("expression took too long to evaluate%s\n", newline);
   else if (sig == SIGFPE)      break;
     printf ("divide by zero%s\n", newline);  
   else  
 #endif  #endif
     case SIGFPE:
       printf ("divide by zero%s\n", newline);
       break;
     default:
     printf ("expression required too much memory to evaluate%s\n", newline);      printf ("expression required too much memory to evaluate%s\n", newline);
       break;
     }
   exit (-2);    exit (-2);
 }  }
   
 /* Return user CPU time measured in milliseconds.  */  
   
 #if defined (USG) || defined (__SVR4) || defined (_UNICOS) || defined (__hpux)  
 #include <time.h>  
   
 int  
 cputime ()  
 {  
   if (CLOCKS_PER_SEC < 100000)  
     return clock () * 1000 / CLOCKS_PER_SEC;  
   return clock () / (CLOCKS_PER_SEC / 1000);  
 }  
 #else  
 #include <sys/types.h>  
 #include <sys/time.h>  
 #include <sys/resource.h>  
   
 int  
 cputime ()  
 {  
   struct rusage rus;  
   
   getrusage (0, &rus);  
   return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;  
 }  
 #endif  

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.1.1.2

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>