Something went wrong. Try again.
A simple, small calculator placed discreetly near the Windows Taskbar or anywhere on the screen taskbar-calculator.marcomaroni.it
Something went wrong. Try again.
taskbar-calculator Calculator.cpp
14 kB · 528 lines
C++
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529#include <windows.h>#include <tchar.h>#include <cmath>#include <cstdio>#include <cstdlib>#include <crtdbg.h>#include "Calculator.h"
#ifdef __AFX_H__#define new DEBUG_NEW#endif
#pragma warning( disable: 4996 )
const int calc::m_max_num_oper=2;
calc::calc(){ m_oper = new double[m_max_num_oper]; m_current_oper=0; m_precision = 2;
m_operator=undefined_oper; m_prev_state=undefined_state; m_state=init;}
calc::~calc(){ delete [] m_oper;}
void calc::set_precision(unsigned int precision){ m_precision = precision;}
unsigned int calc::get_precision(){ return m_precision;}
void calc::change_state(TCHAR newChar, LPCTSTR oldString, LPTSTR newString){ if ( (m_prev_state==undefined_state && m_state==init) || m_state == error ) _tcscpy(newString, CALC_STR_0); else _tcscpy(newString, oldString);
m_prev_state=m_state;
switch(m_prev_state) { case error: case init: switch(newChar) { case CALC_1: case CALC_2: case CALC_3: case CALC_4: case CALC_5: case CALC_6: case CALC_7: case CALC_8: case CALC_9: m_state=first_oper; addChar(newString,newChar); break; case CALC_P: m_state=first_oper; addChar(newString,newChar); break; case CALC_0: m_state=first_oper; break; case CALC_000: m_state=first_oper; break; case CALC_RESET: m_state=init; m_current_oper=0; _tcscpy(newString, CALC_STR_0); break; } break; case first_oper: switch(newChar) { case CALC_1: case CALC_2: case CALC_3: case CALC_4: case CALC_5: case CALC_6: case CALC_7: case CALC_8: case CALC_9: case CALC_0: case CALC_P: m_state=first_oper; addChar(newString,newChar); break; case CALC_000: m_state=first_oper; addString(newString,CALC_STR_000); break; case CALC_ADD: m_state=operation; m_operator=add; addOper(newString); break; case CALC_SUB: m_state=operation; m_operator=sub; addOper(newString); break; case CALC_MUL: m_state=operation; m_operator=mul; addOper(newString); break; case CALC_DIV: m_state=operation; m_operator=div; addOper(newString); break; case CALC_SQRT: m_state=result; m_operator=calc_sqrt; addOper(newString); calcResult(newString); break; case CALC_I: m_state=result; m_operator=inverse; addOper(newString); calcResult(newString); break; case CALC_RESET: m_state=init; m_current_oper=0; _tcscpy(newString,CALC_STR_0); break; case CALC_NEG: changeToNegative(newString); break; } break; case operation: switch(newChar) { case CALC_1: case CALC_2: case CALC_3: case CALC_4: case CALC_5: case CALC_6: case CALC_7: case CALC_8: case CALC_9: case CALC_0: case CALC_P: m_state=second_oper; _tcscpy(newString,CALC_STR_0); addChar(newString,newChar); break; case CALC_RESET: m_state=init; m_current_oper=0; _tcscpy(newString,CALC_STR_0); break; } break; case second_oper: switch(newChar) { case CALC_1: case CALC_2: case CALC_3: case CALC_4: case CALC_5: case CALC_6: case CALC_7: case CALC_8: case CALC_9: case CALC_0: case CALC_P: m_state=second_oper; addChar(newString,newChar); break; case CALC_000: m_state=second_oper; addString(newString,CALC_STR_000); break; case CALC_ADD: addOper(newString); calcResult(newString); m_state=operation; m_operator=add; addOper(newString); break; case CALC_SUB: addOper(newString); calcResult(newString); m_state=operation; m_operator=sub; addOper(newString); break; case CALC_MUL: addOper(newString); calcResult(newString); m_state=operation; m_operator=mul; addOper(newString); break; case CALC_DIV: addOper(newString); calcResult(newString); m_state=operation; m_operator=div; addOper(newString); break; case CALC_SQRT: addOper(newString); calcResult(newString); m_state=operation; m_operator=calc_sqrt; addOper(newString); break; case CALC_I: addOper(newString); calcResult(newString); m_state=operation; m_operator=inverse; addOper(newString); break; case CALC_TOT: m_state=result; addOper(newString); calcResult(newString); break; case CALC_PERC: { opertors oldOpertor = m_operator; double oldFirstOperator = m_oper[0];
m_operator = percent; addOper(newString); calcResult(newString);
m_state = second_oper; m_oper[0] = oldFirstOperator; m_current_oper++; m_operator = oldOpertor; addOper(newString); } break; case CALC_RESET: m_state=init; m_current_oper=0; _tcscpy(newString,CALC_STR_0); break; case CALC_NEG: changeToNegative(newString); break; } break; case result: switch(newChar) { case CALC_1: case CALC_2: case CALC_3: case CALC_4: case CALC_5: case CALC_6: case CALC_7: case CALC_8: case CALC_9: case CALC_P: case CALC_0: m_state=first_oper; _tcscpy(newString,CALC_STR_0); addChar(newString,newChar); break; case CALC_ADD: m_state=operation; m_operator=add; addOper(newString); break; case CALC_SUB: m_state=operation; m_operator=sub; addOper(newString); break; case CALC_MUL: m_state=operation; m_operator=mul; addOper(newString); break; case CALC_DIV: m_state=operation; m_operator=div; addOper(newString); break; case CALC_SQRT: m_state=result; m_operator=calc_sqrt; addOper(newString); calcResult(newString); break; case CALC_I: m_state=result; m_operator=inverse; addOper(newString); calcResult(newString); break; case CALC_RESET: m_state=init; m_current_oper=0; _tcscpy(newString,CALC_STR_0); break; case CALC_NEG: changeToNegative(newString); break; } break; }}
int calc::addChar(LPTSTR string, TCHAR c){ size_t len=_tcslen(string);
if( len+1>MAX_LEN_RESULT ) goto exitOverflow;
if( c==CALC_P && _tcschr(string,c)!=NULL ) goto exitSequenceError;
if( len==1 && string[0]=='0' && c=='0' ) goto exitSequenceError;
if( len==1 && string[0]=='0' && c!='0' && c!=CALC_P ) { len=0; string[0]='\0'; }
string[len]=c; string[len+1]='\0';
return 1;
exitSequenceError: return 0;
exitOverflow: err(overflow, string); return 0;}
int calc::addString(LPTSTR string, LPTSTR str2){ size_t len=_tcslen(string); size_t len2=_tcslen(str2); if( len+len2>MAX_LEN_RESULT ) goto exitOverflow;
if( _tcscmp(str2,CALC_STR_P)==0 && _tcsstr(string,CALC_STR_P)!=NULL ) goto exitSequenceError;
if( len==1 && string[0]=='0' && _tcscmp(str2,CALC_STR_0)==0 ) goto exitSequenceError;
if( len==1 && string[0]=='0' && _tcscmp(str2,CALC_STR_000)==0 ) goto exitSequenceError;
if( len==1 && string[0]=='0' && _tcscmp(str2,CALC_STR_0)!=0 && _tcscmp(str2,CALC_STR_P)!=0 ) string[0]='\0';
_tcscat(string,str2); return 1;
exitSequenceError: return 0;
exitOverflow: err(overflow, string); return 0;}
int calc::addOper(LPTSTR string){ _ASSERT(m_current_oper<=m_max_num_oper);
m_oper[m_current_oper]=_tstof(string);
if( _tcscmp(string,CALC_STR_0)!=0 && m_oper[m_current_oper]==0) { err(overflow, string); return 0; }
m_current_oper++; return 1;}
int calc::calcResult(LPTSTR string){ double result=0;
switch(m_operator) { case undefined_oper: goto exitSequenceError; case add: result=m_oper[0]+m_oper[1]; break; case sub: result=m_oper[0]-m_oper[1]; break; case div: if(m_oper[1]!=0) result=m_oper[0]/m_oper[1]; else goto exitDivisionByZero; break; case mul: result=m_oper[0]*m_oper[1]; break; case calc_sqrt: result = sqrt(m_oper[0]); break; case inverse: result = (1/m_oper[0]); break; case percent: result = (m_oper[1]*m_oper[0])/100; }
TCHAR tmp_string[100]; _stprintf(tmp_string, L"%.*lf", (int)m_precision, (double)result); trimRigthDecimalZero(tmp_string); if(_tcslen(tmp_string)>MAX_LEN_RESULT) goto exitOverflow; else _tcscpy(string,tmp_string);
m_current_oper=0; return 1;
exitSequenceError: m_current_oper=0; return 0;
exitOverflow: err(overflow, string); m_current_oper=0; return 0;
exitDivisionByZero: err(division_by_zero, string); m_current_oper=0; return 0;}
int calc::trimRigthDecimalZero(LPTSTR string){ if(_tcschr(string,CALC_P)==NULL) return 1;
size_t i = _tcslen(string);
i--; while(string[i]!=CALC_P && string[i]==CALC_0) { string[i]='\0'; i--; }
if(string[i]==CALC_P) string[i]='\0';
return 1;}
void calc::err(int errorCode, LPTSTR string){ switch(errorCode) { case overflow: if( string != NULL ) _tcscpy(string, ERR_STR_OVERFLOW); m_state = error; break; case division_by_zero: if( string != NULL ) _tcscpy(string, ERR_STR_DIVBYZERO); m_state = error; break; }}
int calc::changeToNegative(LPTSTR string){ double d = _tstof(string); d = d * -1; _stprintf(string, L"%.*lf", (int)m_precision, (double)d); trimRigthDecimalZero(string); return 1;}