home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS - Coast to Coast
/
simteldosarchivecoasttocoast2.iso
/
calculat
/
c_calc10.zip
/
C-CALC.CPP
next >
Wrap
C/C++ Source or Header
|
1993-05-03
|
11KB
|
396 lines
/***************************************************************************
************************ C-CALC.CPP ************************************
****************************************************************************
Version 1.0 of C-CALC.CPP by Joe Spector May 3, 1993.
Freeware.
Complex Number Calculator:
CopyJoe policy:
You can do anything they like with the program or source code
except sell it or any part of it.
This program has been tested using Borland C++ 3.1
Motivation for c-calc:
To allow simple evaluation of complex number expressions where
the complex numbers may be entered in polar or xy notation or
combinations of the two.
e.g.
to evaluate this
(1.2 + 1.4i)(4*exp(2.3i))
---------------------------
1 + 2.3j + 4exp(0.3i)
the user would type in the following:
1.2,1.4 <--- , means entered as xy
4d2.3 <--- d means polar (in degrees)
* if 2.3 was radians the entry would
1,2.3 be 4r2.3
4d0.3
+
/
Most of the usual functions one sees on a scientific calculator
are also available, e.g.
pi
4
/
sin
would calculate sin(pi/4) or
1r0.5
sin
would calculate sin(1exp(i0.5)) where 0.5 is the phase angle in
radians
1,1
sqrt
evaluates sqrt(1+i), etc.
Bad things about this program:
1) Each operation must be terminated by hitting the <enter> key.
2) Computer used to run this program is typically much bigger
than an HP calculator.
3) Memory values may run off top of screen if too many are shown.
See item 3) in Other Notes: below.
4) Help screen is ugly (quite cryptic). To fix it change the
code in the function help() if you want to.
5) Lot's of other stuff, I'm sure.
Other Notes:
1) There is a stack and a bank of memories. The size of each is
determined by the constants STACKSIZE and MEMSIZE set to 10
and 100 in the program. Only STACKDISPLAYSIZE (set to 4)
stack values are shown.
2) The stack and memory are read and stored each time the program
is run into the file named by the constant INFILE set to
"c-calc.ini" below. If INFILE does not exist when beginning
the program, all stack and memory locations are set to zero.
3) The memory locations which contain nonzero entries are not
shown. All others are shown. Nonzero is measured by using the
inline function approxzero().
*****************************************************************************
*****************************************************************************
*****************************************************************************/
#include <iostream.h>
#include <stdio.h>
#include <complex.h>
#include <ctype.h> // for toupper()
#include <string.h> // for strcpy()
#include <conio.h> // for getch()
#define STACKSIZE 10
#define STACKDISPLAYSIZE 4
#define MEMSIZE 100
#define DEGREE char(248)
#define INIFILE "c-calc.ini"
complex j(0,1);
int radian_mode=0; // 0 means degrees mode
inline double deg(double rad) {return (180.0*rad/M_PI);};
inline double rad(double deg) {return (M_PI*deg/180.0);};
inline double mag(complex c) {return(sqrt(norm(c)));};
// suffix d means angle arguement is in degrees rather than radians
inline double argd(complex c) {return(deg(arg(c)));};
inline int approxzero(complex c) {return (mag(c)<1.0e-100);}
inline complex polard(double mag, double deg) { return polar(mag,rad(deg));};
inline void showboth(complex c)
{
cout << c << " = " << mag(c) << " @ ";
if (radian_mode) cout << arg(c) << "rad\n";
else cout << argd(c) << DEGREE << endl;
};
//GLOBAL VARIABLES: c[] stack(RPN-like) m[] memory
complex c[STACKSIZE];
complex m[MEMSIZE];
void showbriefhelp();
void showmemory();
void showstack();
complex GetReal(char *s);
complex GetComplex(char *s);
void Operate(char *s);
void rollup(complex z);
void rolldown();
void help();
void store(char *s);
void retrieve(char *s);
void readini();
void writeini();
main()
{
char s[80];
char ch;
double x,y;
readini();
do
{
clrscr();
showbriefhelp();
showmemory();
showstack();
scanf("%s",s);
int i=sscanf(s,"%lg %c %lg",&x,&ch,&y);
switch (i)
{
case 3: rollup(GetComplex(s)); break;
case 1: rollup(GetReal(s)); break;
default : Operate(s);
}
} while (strcmpi(s,"q")!=0);
writeini();
return 0;
}
void help()
{
clrscr();
cout << "Complex Number Entry:" << endl;
cout << " 2.1 x-y with y=0" << endl;
cout << " 2x1 or 2,1 x-y" << endl;
cout << " 1d45 polar (degrees) 1 @ 45 degrees" << endl;
cout << " 1r3.14 polar (radians) 1 @ 3.14 radians" << endl;
cout << " q to quit" << endl;
cout << "Other stuff you can enter: (..) after item gives brief reminder:" << endl;
cout << " * / + - ^ (x^y) sqr sqrt (careful about branch cut)" << endl;
cout << " inv cs(change sign) conj pi j i (j,i both sqrt(-1)) e(enter)" << endl;
cout << " [a]sin [a]cos [a]tan exp ln (log_e) log (log_10) db (20log_10)" << endl;
cout << " arg[d] (phase angle in radians[degrees])" << endl;
cout << " rd dr (* or / by 180/pi i.e. rad <--> deg)" << endl;
cout << " r d (to rad or deg mode) swap (re <-->imag)" << endl;
cout << " xy (x <--> y) cm cstack ca (clear mem or stack or all(both))" << endl;
cout << " >n <n (memory store retrieve 0<n<" << MEMSIZE << ")" ;
cout << endl << endl;
cout << " hit any key to continue .. ";
getch();
}
void showbriefhelp()
{
cout << "\nh for help q to quit\n";
}
void showmemory()
{
int j=0;
cout << "MEMORY:" << endl;
for(int i=0;i<MEMSIZE;i++)
if (!(approxzero(m[i]))) //ONLY DISPLAY NONZERO MEMORIES
{
cout << i << ": " << m[i];
if (j==0)
{
j=1;
cout << " ";
}
else
{
j=0;
cout << endl;
}
}
if (j==1) cout << endl;
}
void showstack()
{
cout << "STACK:" << endl;
for(int i=STACKDISPLAYSIZE-1;i>=0;i--) showboth(c[i]);
}
complex GetReal(char *s)
{
double x;
if (sscanf(s,("%lg"),&x)==1) return complex(x,0.0);
else return complex(0.0,0.0);
}
complex GetComplex(char *s)
{ double x,y;
char ch;
if (sscanf(s,"%lg %c %lg",&x,&ch,&y)==3)
{
//cin >> x >> c >> y;
ch=toupper(ch);
switch (ch)
{
case 'R': return polar(x,y);
case 'D': return polard(x,y);
case 'X': return complex(x,y);
case ',': return complex(x,y);
}
}
return complex(0.0,0.0);
}
void Operate(char *s)
{
complex temp;
if (s[0]=='<') {retrieve(s);}
else if (s[0]=='>') {store(s);}
else if (strcmpi(s,"d")==0) {radian_mode=0;}
else if (strcmpi(s,"r")==0) {radian_mode=1;}
else if (strcmpi(s,"*")==0) {c[0]=c[1]*c[0]; rolldown();}
else if (strcmpi(s,"/")==0)
{if(!approxzero(c[0])){c[0]=c[1]/c[0]; rolldown();}}
else if (strcmpi(s,"+")==0) {c[0]=c[1]+c[0]; rolldown();}
else if (strcmpi(s,"-")==0) {c[0]=c[1]-c[0]; rolldown();}
else if (strcmpi(s,"^")==0) {c[0]=pow(c[0],c[1]); rolldown();}
else if (strcmpi(s,"j")==0) {rollup(j);}
else if (strcmpi(s,"i")==0) {rollup(j);}
else if (strcmpi(s,"h")==0) {help();}
else if (strcmpi(s,"?")==0) {help();}
else if (strcmpi(s,"sin")==0) {c[0]=sin(c[0]);}
else if (strcmpi(s,"cos")==0) {c[0]=cos(c[0]);}
else if (strcmpi(s,"tan")==0) {c[0]=tan(c[0]);}
else if (strcmpi(s,"asin")==0) {c[0]=asin(c[0]);}
else if (strcmpi(s,"acos")==0) {c[0]=acos(c[0]);}
else if (strcmpi(s,"atan")==0) {c[0]=atan(c[0]);}
else if (strcmpi(s,"ln")==0) {c[0]=log(c[0]);}
else if (strcmpi(s,"log")==0) {c[0]=log10(c[0]);}
else if (strcmpi(s,"db")==0) {c[0]=20*log10(c[0]);}
else if (strcmpi(s,"exp")==0) {c[0]=exp(c[0]);}
else if (strcmpi(s,"sqr")==0) {c[0]=c[0]*c[0];}
else if (strcmpi(s,"sqrt")==0) {c[0]=sqrt(c[0]);}
else if (strcmpi(s,"inv")==0)
{if(!approxzero(c[0])) {c[0]=1.0/c[0]; }}
else if (strcmpi(s,"cs")==0){c[0]= -c[0];}
else if (strcmpi(s,"pi")==0){rollup(complex(M_PI));}
else if (strcmpi(s,"swap")==0)
{c[0]=complex(imag(c[0]),real(c[0]));}
else if (strcmpi(s,"xy")==0)
{temp=c[0];c[0]=c[1];c[1]=temp;}
else if (strcmpi(s,"dr")==0)
{c[0]=complex(rad(real(c[0])),rad(imag(c[0])));}
else if (strcmpi(s,"rd")==0)
{c[0]=complex(deg(real(c[0])),deg(imag(c[0])));}
else if (strcmpi(s,"cm")==0)
{for(int i=0;i<MEMSIZE;i++) m[i]=complex(0.0,0.0);}
else if (strcmpi(s,"cstack")==0)
{for(int i=0;i<STACKSIZE;i++) c[i]=complex(0.0,0.0);}
else if (strcmpi(s,"conj")==0)
{c[0]=conj(c[0]);}
else if (strcmpi(s,"arg")==0)
{c[0]=complex(arg(c[0]),0.0);}
else if (strcmpi(s,"argd")==0)
{c[0]=complex(argd(c[0]),0.0);}
else if (strcmpi(s,"e")==0)
{rollup(c[0]);}
else if (strcmpi(s,"ca")==0)
{for(int i=0;i<STACKSIZE;i++) c[i]=complex(0.0,0.0);}
return;
}
void rollup(complex z)
{
for(int i=STACKSIZE-1;i>0;i--) c[i]=c[i-1];
c[0]=z;
}
void rolldown()
{
for(int i=1;i<STACKSIZE-1;i++) c[i]=c[i+1];
c[STACKSIZE-1]=complex(0,0);
}
void store(char *s)
{
int i;
if (sscanf(s+1,"%d",&i)==1)
if (i>=0&&i<MEMSIZE) m[i]=c[0];
}
void retrieve(char *s)
{
int i;
if (sscanf(s+1,"%d",&i)==1)
if (i>=0&&i<MEMSIZE) rollup(m[i]);
}
void readini()
{
FILE *f;
int ss,ms;
double x,y;
if((f=fopen(INIFILE,"r"))==NULL) return;
fscanf(f,"%d %d",&ss,&ms);
for(int i=0;i<ss;i++)
if(i<STACKSIZE)
{
fscanf(f,"%lg %lg",&x,&y);
c[i]=complex(x,y);
}
for(i=0;i<ms;i++)
if(i<MEMSIZE)
{
fscanf(f,"%lg %lg",&x,&y);
m[i]=complex(x,y);
}
fclose(f);
return;
}
void writeini()
{
FILE *f;
f=fopen(INIFILE,"w");
fprintf(f,"%d %d\n",STACKSIZE,MEMSIZE);
for(int i=0;i<STACKSIZE;i++)
fprintf(f,"%12.8e %12.8e\n",real(c[i]),imag(c[i]));
for(i=0;i<MEMSIZE;i++)
fprintf(f,"%12.8e %12.8e\n",real(m[i]),imag(m[i]));
fclose(f);
return;
}