Привет форумчани. Написал я программу что-то на подобия калькулятора который работает с математическими выражениями. Все отлично работает но препод нашел небольшой изъян, это программа не может вычислит разделения на 0 (то что x/0= бесконечность я знаю), это приводить к странной ошибке: 1.#INF . я бы хотел спросить как написать функцию которая определяет бесконечность. Заранее спасибо за ответы.
Код:
#include <iostream.h>
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
enum types {DELIMITER=1,VARIABLE,NUMBER};
class Parser
{ char *exp_ptr;
char token[80];
char tok_type;
void eval_exp2(double &result);
void eval_exp3(double &result);
void eval_exp4(double &result);
void eval_exp5(double &result);
void eval_exp6(double &result);
void atom(double &result);
void get_token();
void serror (int error);
int isdelim(char c);
public:
Parser();
double eval_exp(char *exp);};
Parser::Parser()
{exp_ptr=NULL;}
double Parser::eval_exp(char *exp)
{double result;
exp_ptr=exp;
get_token();
if(!*token){
serror(2);
return 0.0;}
eval_exp2(result);
if(*token)serror(0);
return result;}
void Parser::eval_exp2(double &result)
{register char op;
double temp;
eval_exp3(result);
while((op=*token)=='+'||op=='-'){
get_token();
eval_exp3(temp);
switch(op){
case '-':
result-=temp;
break;
case '+':
result+=temp;
break;}}}
// umnojaem ili delim dva faktora
void Parser::eval_exp3(double &result){
register char op;
double temp;
eval_exp4(result);
while((op = *token) == '*' || op == '/' || op == '%'){
get_token();
eval_exp4(temp);
switch(op){
case '*':
result *= temp;
break;
case '/':
result /= temp;
break;
case '%':
result = (int)result % (int)temp;
break; } }}
void Parser::eval_exp4(double &result){
double temp, ex;
register int t;
eval_exp5(result);
if(*token == '^'){
get_token();
eval_exp4(temp);
ex = result;
if (temp == 0.0){
result = 1.0;
return; }
for(t=(int)temp-1; t>0; --t) result *= (double)ex; }}
//vichislenie unarnix operatsiy + ili -
void Parser::eval_exp5(double &result){
register char op;
op = 0;
if((tok_type == DELIMITER) && *token == '+' || *token == '-'){
op = *token;
get_token(); }
eval_exp6(result);
if(op == '-') result = -result;}
// raspoznavanie skobok
void Parser::eval_exp6(double &result){
if ((*token == '(')){
get_token();
eval_exp2(result);
if(*token != ')') serror(1);
get_token();
} else atom(result);}
// poluchaet chislo
void Parser:: atom(double &result){
switch(tok_type){
case NUMBER:
result = atof(token);
get_token();
return;
default:
serror(0); }}
void Parser::serror(int error){
static char *e[]={
"Syntactic error",
"Error in use braces",
"Empty expression" };
cout << e[error]<<endl;}
// to get next token
void Parser::get_token(){
register char *temp;
tok_type = 0;
temp = token;
*temp = '\0';
if (!*exp_ptr) return; // v konse virajenia
while(isspace(*exp_ptr)) ++exp_ptr; // propusk razdelitelya
if(strchr("+-*/%^=()", *exp_ptr)){
tok_type = DELIMITER;
// perexod na sleduyushiy simvol
*temp++ = *exp_ptr++;
} else if(isalpha(*exp_ptr)){
while(!isdelim(*exp_ptr)) *temp++ = *exp_ptr++;
tok_type = VARIABLE;
} else if(isdigit(*exp_ptr)){
while(!isdelim(*exp_ptr)) *temp++ = *exp_ptr++;
tok_type = NUMBER; }
*temp = '\0'; }
// esli parameter s yavlyaetsya razdelitelelem
// vozvrashaet znachenie true
int Parser::isdelim(char c){
if(strchr(" +-/*%^=()", c) || c==9 || c=='\r' || c==0)
return 1; return 0; }
int main(int argc, char* argv[])
{ char expstr[80];
Parser ob;
for(;;){
cout<<"Vvedite virajeniya: ";
cin.getline(expstr, 79);
if(*expstr=='.') break;
cout<<"Otvet: "<<ob.eval_exp(expstr)<<"\n\n"; }; getch();
return 0;}
//------------------