⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 calc.c

📁 任意精度的数学库
💻 C
字号:
/*  *  M_APM  -  calc.c * *  Copyright (C) 1999   Michael C. Ring * *  Permission to use, copy, and distribute this software and its *  documentation for any purpose with or without fee is hereby granted,  *  provided that the above copyright notice appear in all copies and  *  that both that copyright notice and this permission notice appear  *  in supporting documentation. * *  Permission to modify the software is granted, but not the right to *  distribute the modified code.  Modifications are to be distributed  *  as patches to released version. *   *  This software is provided "as is" without express or implied warranty. *//* *      $Id: calc.c,v 1.6 1999/07/05 15:06:04 mike Exp $ * *      RPN Calculator : demo of the MAPM math library * *      This file contains the validation test program. It compares  *	the M_APM library to the standard C lbrary math functions. * *      $Log: calc.c,v $ *      Revision 1.6  1999/07/05 15:06:04  mike *      added DUP operator * *      Revision 1.5  1999/06/01 02:35:00  mike *      fix isdigit call with cast * *      Revision 1.4  1999/05/28 21:17:11  mike *      break up usage into 2 printf so dos compile doesnt choke * *      Revision 1.3  1999/05/19 02:29:44  mike *      added version of calc to usage line * *      Revision 1.2  1999/05/19 02:18:33  mike *      added check for stack under-flow * *      Revision 1.1  1999/05/19 02:01:02  mike *      Initial revision */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include "m_apm.h"/*  prototypes for functions in this file  */void	 calc_reciprocal(M_APM, int, M_APM);void	 calc_square(M_APM, int, M_APM);void	 calc_pi(M_APM, int);char 	 *lowercase(char *);char	 *out_buffer;char	 in_buffer[4096];#define  STACK_SIZE 96M_APM    calc_stack_data[STACK_SIZE];#define NUM_OPERATOR_ENTRIES 27          /* number of operators *//* calling convention for various MAPM library functions ... */#define	MMM     0x0A01                   /*  ( MAPM, MAPM, MAPM )       */#define	MiMM    0x0A02                   /*  ( MAPM, int, MAPM, MAPM )  */#define	MiM     0x0A03                   /*  ( MAPM, int, MAPM )        */#define	Mi      0x0A04                   /*  ( MAPM, int )              */#define	MM      0x0A05                   /*  ( MAPM, MAPM )             */#define	MXY     0x0A80                   /*  special for x <> y         */#define	MDUP    0x0A81                   /*  special for dup            */#define	M_END   0x0AFF                   /*  end of table flag          */struct  opstr {  char  operator[16];        int	calling_convention;  void	(*funcname)();};struct  opstr  operator_lookup[NUM_OPERATOR_ENTRIES] = {     {  "+",    MMM,     m_apm_add,             /*   0   */  },   {  "-",    MMM,     m_apm_subtract,        /*   1   */  },   {  "*",    MMM,     m_apm_multiply,        /*   2   */  },   {  "x",    MMM,     m_apm_multiply,        /*   3   */  },   {  "/",    MiMM,    m_apm_divide,          /*   4   */  },   {  "\\",   MMM,     m_apm_integer_divide,  /*   5   */  },   {  "i",    MMM,     m_apm_integer_divide,  /*   6   */  },   {  "!",    MM,      m_apm_factorial,       /*   7   */  },   {  "s",    MiM,     m_apm_sin,             /*   8   */  },   {  "c",    MiM,     m_apm_cos,             /*   9   */  },   {  "t",    MiM,     m_apm_tan,             /*  10   */  },   {  "q",    MiM,     m_apm_sqrt,            /*  11   */  },   {  "as",   MiM,     m_apm_arcsin,          /*  12   */  },   {  "ac",   MiM,     m_apm_arccos,          /*  13   */  },   {  "at",   MiM,     m_apm_arctan,          /*  14   */  },   {  "at2",  MiMM,    m_apm_arctan2,         /*  15   */  },   {  "lg",   MiM,     m_apm_log,             /*  16   */  },   {  "lg10", MiM,     m_apm_log10,           /*  17   */  },   {  "e",    MiM,     m_apm_exp,             /*  18   */  },   {  "p",    MiMM,    m_apm_pow,             /*  19   */  },   {  "h",    MM,      m_apm_negate,          /*  20   */  },   {  "xy",   MXY,     NULL,                  /*  21   */  },   {  "d",    MDUP,    NULL,                  /*  22   */  },   {  "r",    MiM,     calc_reciprocal,       /*  23   */  },   {  "x2",   MiM,     calc_square,           /*  24   */  },   {  "pi",   Mi,      calc_pi,               /*  25   */  },   {  "ZZZ",  M_END,   NULL                   /*  26   */  } }; int main(argc, argv)int argc;  char *argv[];{void	 (*fp)();char     *cp;int      ii, ilow, stack_pointer, decimal_places, k;M_APM    apmtmp;M_APM    arg1;   M_APM    arg2;if (argc < 2)  {   fprintf(stderr,"calc [-d##] <numbers,operators>\t\t\t\t[Version 1.1]\n");   fprintf(stderr,"      -d : specify decimal places, default = 20\n\n");   fprintf(stderr,"operators :  + : add                           s : sin\n\             - : subtract                      c : cos\n\             x : multiply (*)                  t : tan\n\             / : divide                        q : sqrt\n\             \\ : integer divide (i)           as : arc-sin\n\             ! : factorial                    ac : arc-cos\n");   fprintf(stderr,"            x2 : x ^ 2                        at : arc-tan\n\             r : 1 / x                       at2 : arc-tan2 (y,x)\n\            lg : log                           e : e ^ x\n\          lg10 : log10                         p : y ^ x\n\            xy : x<>y (exchange x,y)           h : +/- (change sign)\n\             d : dup                          pi : 3.14159.. \n\");   exit(2);  }/* leave arg1, arg2 uninitialized on purpose *//*                                           *//* analagous to  :   int  *arg1, buffer[NN]; *//*                   arg1 = buffer;          */apmtmp = m_apm_init();for (k=0; k < STACK_SIZE; k++)  calc_stack_data[k] = m_apm_init();/* *   normally, stack_pointer would be 0 and we would  *   check all operations on it to verify it never  *   went < 0. since this is a just demo program and not *   a 'real' application, we will just warn the user *   at the end if a potential stack underflow occurred. *   we can likely force a run-time core dump with 16  *   math operations with no numbers to work with : *   i.e. -> calc + + + + ... 16 times */stack_pointer  = 16;decimal_places = 20;ilow           = 1;strcpy(in_buffer, argv[1]);lowercase(in_buffer);if ((cp = strstr(in_buffer,"-d")) != NULL)  {   ilow++;   cp += 2;   decimal_places = atoi(cp);   if (decimal_places < 2)     decimal_places = 2;  }for (ii=ilow; ii < argc; ii++)  {   strcpy(in_buffer, argv[ii]);   lowercase(in_buffer);   k = 0;   while (1)     {              /*       *  if we reached the end of the table or the first       *  char is a digit, we assume this is a number        */      if (operator_lookup[k].calling_convention == M_END ||           isdigit((int)*in_buffer))        {	 stack_pointer++;	 m_apm_set_string(calc_stack_data[stack_pointer], in_buffer);	 break;	}      if (strcmp(operator_lookup[k].operator, in_buffer) == 0)        {         /*          *  we found an operator, so do it           */	 if (operator_lookup[k].calling_convention == Mi)	   {            fp = operator_lookup[k].funcname;            (*fp)(apmtmp, decimal_places);	    m_apm_copy(calc_stack_data[++stack_pointer], apmtmp);	   }		 if (operator_lookup[k].calling_convention == MXY)	   {	    arg2 = calc_stack_data[stack_pointer - 1];	    arg1 = calc_stack_data[stack_pointer];	    m_apm_copy(apmtmp, arg1);	    m_apm_copy(arg1, arg2);	    m_apm_copy(arg2, apmtmp);	   }		 if (operator_lookup[k].calling_convention == MDUP)	   {	    arg1 = calc_stack_data[stack_pointer];	    m_apm_copy(calc_stack_data[++stack_pointer], arg1);	   }		 if (operator_lookup[k].calling_convention == MMM)	   {            fp   = operator_lookup[k].funcname;	    arg2 = calc_stack_data[stack_pointer];	    arg1 = calc_stack_data[--stack_pointer];            (*fp)(apmtmp, arg1, arg2);	    m_apm_copy(arg1, apmtmp);	   }		 if (operator_lookup[k].calling_convention == MiMM)	   {            fp   = operator_lookup[k].funcname;	    arg2 = calc_stack_data[stack_pointer];	    arg1 = calc_stack_data[--stack_pointer];            (*fp)(apmtmp, decimal_places, arg1, arg2);	    m_apm_copy(arg1, apmtmp);	   }		 if (operator_lookup[k].calling_convention == MM)	   {            fp   = operator_lookup[k].funcname;	    arg1 = calc_stack_data[stack_pointer];            (*fp)(apmtmp, arg1);	    m_apm_copy(arg1, apmtmp);	   }		 if (operator_lookup[k].calling_convention == MiM)	   {            fp   = operator_lookup[k].funcname;	    arg1 = calc_stack_data[stack_pointer];            (*fp)(apmtmp, decimal_places, arg1);	    m_apm_copy(arg1, apmtmp);	   }	 break;	}      k++;     }  }if ((out_buffer = (char *)malloc(decimal_places + 16)) == NULL)  {   fprintf(stderr,"out of memory\n");   exit(6);  }if (stack_pointer <= 16)  {   fprintf(stderr,"Warning!, stack under-flow, result is unreliable\n");  }arg1 = calc_stack_data[stack_pointer];m_apm_round(apmtmp, decimal_places, arg1);m_apm_to_string(out_buffer, -1, apmtmp);printf("%s\n",out_buffer);for (k=0; k < STACK_SIZE; k++)  m_apm_free(calc_stack_data[k]);m_apm_free(apmtmp);free(out_buffer);exit(0);}/***********************************************************************/void	 calc_reciprocal(rr, p, xx)M_APM	 rr, xx;int	 p;{m_apm_divide(rr, p, MM_One, xx);}/***********************************************************************/void	 calc_square(rr, p, xx)M_APM	 rr, xx;int	 p;{m_apm_multiply(rr, xx, xx);}/***********************************************************************/void	 calc_pi(rr, p)M_APM	 rr;int	 p;{m_apm_round(rr, p, MM_PI);}/***********************************************************************/char	*lowercase(s)char    *s;{register char *p;p = s;while (1)  {   if (*p >= 'A' && *p <= 'Z')  *p += 'a' - 'A';   if (*p++ == 0)  break;  }return(s);}/***********************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -