- 热门文章:
- · 利用SNIFFER PRO学习TCP/IP(一)
- · 利用SNIFFER PRO学习TCP/IP(二)
- · 用VC++进行MapX二次开发::之一------地理信息系统概述
- · 用VC++进行MapX二次开发::之二------使用MapX的基石
- · 用VC++进行MapX二次开发::之三------使用MapX工具
- · 有关引用以及LoadBitmap几个容易混淆的问题
- · 打印的简单实现,以及更改打印设置
- · 如何按照线型画粗线
- · 品赏Apache源码中的apr_dbg_log函数
- · Windows MFC编程之一 最简单的MFC程序
- · 如何在BCB中正确链接WinAPI函数AlphaBlend()实现半透明效果
- · 如何在BCB中配置和使用GDI+技术?(附动画实例)
表达式求值(下)
//函数处理
bool CExpression::Level6(double *result)
{
int num; char funcname[8];
char op = 0;
int paranum=1;
double para[6];
if( IsFunc( m_strToken ) ) // 如果是函数名
//if(expGetFunIndex(m_strToken,&num) == true)
{
op = 1;
strcpy( funcname, m_strToken );
//取得下一单元
if(GetToken() != true)
{
m_iErrFlag = 2; //m_iErrFlag = 1;
return false;
}
}
if(op)
{
if((*m_strToken == ´(´) && (m_cTokenType == DELIMITER))
{
//取得括号内第一单元
if(GetToken() == true)
{
//递归调用,完成括号内的表达式运算
if(Level2(result) != true)
return false;
while(m_cTokenType == DELIMITER && *m_strToken == ´,´)
{
paranum++;
if(GetToken() != true)
{
m_iErrFlag = 2; //m_iErrFlag = 1;
return false;
}
//递归调用,完成括号内的表达式运算
if(Level2(¶[paranum-1]) != true)
return false;
}
para[0] = *result;
//当前符号应为´)´
if(*m_strToken != ´)´)
{
//括号不匹配
m_iErrFlag = 3;
return false;
}
if(GetToken() != true)
{
m_iErrFlag = 2; //m_iErrFlag = 1;
return false;
}
}
else
{
m_iErrFlag = 2; //m_iErrFlag = 1;
return false;
}
}
else
{
//括号不匹配
m_iErrFlag = 3;
return false;
}
//单参数
if(paranum == 1)
{
*result = para[0];
//若函数为三角函数,进行角度到弧度的转换
if(stricmp(funcname,"sin") == 0 ||
stricmp(funcname,"cos") == 0 ||
stricmp(funcname,"tan") == 0 )
{
if( stricmp( funcname, "tan" ) == 0 )
{
if( fabs( *result - 90.0 ) < 0.0005 ||
fabs( *result - 270.0 ) < 0.0005 ||
fabs( *result + 90.0 ) < 0.0005 ||
fabs( *result + 270.0 ) < 0.0005 )
{
Message( "正切函数值溢出!" );//
return false;
}
}
if( m_bDegUnit == true )
*result = *result /180 * PI;
}
else if( stricmp(funcname,"asin") == 0 ||
stricmp(funcname,"acos") == 0 )
{
if( fabs( *result ) > 1.0 )
{
//
Message( "反正弦函数和反余弦函数的参数绝对值必须小于1!" );
return false;
}
}
else if( stricmp( funcname, "sqrt" ) == 0 )
{
if( *result < 0.0 )
{
Message( "不能对负数开平方!" );//
return false;
}
}
else if( stricmp( funcname, "log" ) == 0 ||
stricmp( funcname, "log10" ) == 0 )
{
if( *result <= 0.0 )
{
Message( "负数和零没有对数!" );//
return false;
}
}
if( GetFunIndex( funcname, &num ) )
*result = ( *funTable[num])(*result);
else
{
m_iErrFlag = 2;
return false;
}
}
else
return false;
if(paranum == 1)
{
//若为反三角函数,将弧度转化为度
if(stricmp(funcname,"asin") == 0 ||
stricmp(funcname,"acos") == 0 ||
stricmp(funcname,"atan") == 0 )
{
if( m_bDegUnit == true )
*result = *result *180 / PI;
}
return true;
}
}
if(Level7(result) != true)
return false;
return true;
}
//括号及函数处理
bool CExpression::Level7(double *result)
{
//若取得的单元为括号
if((*m_strToken == ´(´) && (m_cTokenType == DELIMITER))
{
//跳过括号,取得括号内第一单元
if(GetToken() == true)
{
//递归调用,完成括号内的表达式运算
if(Level2(result) != true)
return false;
//当前符号应为´)´,否则出错
if(*m_strToken != ´)´)
{
m_iErrFlag = 3;
return false;
}
//跳过符号´)´
if(GetToken() != true)
{
m_iErrFlag = 3;
return false;
}
}
else
{
m_iErrFlag = 2; //m_iErrFlag = 1;
return false;
}
}
//否则必为变量或常数
else
{
//取得变量数值或常数
if(Primitive(result) != true)
{
m_iErrFlag = 2;
return false;
}
else
return true;
}
return true;
}
bool CExpression::GetFunIndex(const char *name,int *index)
{
int i;
for(i=0 ;i< funTableLen ;i++)
{
if(strcmp(funNameTable[i],name) == 0)
{
*index = i;
return true;
}
}
return false;
}
//回读表达式一token,在level1中调用.
void CExpression::PutBack()
{
char *t;
//将token回送到表达式
t = m_strToken;
for( ; *t; t ++ )
m_strExp--;
}
//取反
void CExpression::Unary(char o,double *r)
{
if(o == ´-´)
*r = -(*r);
}
bool CExpression::Arith(char o, double *r, double *h)
{
int t;
double ex;
switch(o)
{
case ´-´:
*r=*r - *h;
break;
case ´+´:
*r=*r + *h;
break;
case ´*´:
*r=*r * *h;
break;
case ´/´:
if(fabs(*h)<0.00000001)
{
Message("除数为零!" ); //
return false;
}
*r=(*r) / (*h);
break;
case ´%´:
t=(int)( (*r) / (*h) );
*r=*r- t*(*h);
break;
case ´^´: // 原有处理如果指数为小数则结果误差很大
ex=*r;
if( fabs( *h ) < 1e-9 )
{
*r=1.0;
break;
}
if( fabs( *h - floor( *h ) ) < 0.01 || fabs( *h - ceil( *h ) ) < 0.01 )
{
for( t = (int)(*h) - 1; t > 0; t -- )
*r = (*r) * ex;
}
else
*r = pow( *r, *h );
break;
}
return true;
}
//取变量或常数值
bool CExpression::Primitive(double *result)
{
if(strcmp(m_strToken,"") == 0)
return true;
//常数
if(m_cTokenType == NUMBER)
{
//串转化为实数
*result = atof(m_strToken);
//取得下一单元
if(GetToken() != true)
return false;
return true;
}
//变量
else if(m_cTokenType == VARIABLE)
{
if(GetVarValue(m_strToken,result) != true)
return false;
//取得下一单元
if(GetToken() != true)
return false;
return true;
}
return false;
}
bool CExpression::GetVarValue( const char * n, double * result )
{
list<CVar*>::iterator iter;
for(iter=m_VarList.m_VarList.begin();iter!=m_VarList.m_VarList.end();iter++)
{
if((*iter)->m_strName==n)
{
*result=(*iter)->m_dValue;
return true;
}
}
return false;
}
//取得变量在变量表中的索引值
bool CExpression::GetVarIndex( const char * name, int * index )
{
int i=0;
list<CVar*>::iterator iter;
for(iter=m_VarList.m_VarList.begin();iter!=m_VarList.m_VarList.end();iter++)
{
if((*iter)->m_strName==name)
{
*index=i;
return true;
}
i++;
}
return false;
}
bool CExpression::UpdateSlaveVar()
{
bool bRet = true;
list<CVar*>::iterator iter;
for(iter=m_VarList.m_VarList.begin();iter!=m_VarList.m_VarList.end();iter++)
{
if((*iter)->m_strSlave!="")
{
double dResult=m_dResult;
char* strExp=m_strExp;
string str=(*iter)->m_strSlave;
m_strExp=(char*)str.c_str();
(*iter)->m_strSlave="";
bRet=CalExp();
if(bRet==false)
{
string prompt=(*iter)->m_strName;
prompt+="定义错误!";
Message(prompt.c_str());
return false;
}else
{
(*iter)->m_dValue=m_dResult;
}
m_dResult=dResult;
m_strExp=strExp;
}
}
return true;
}
- · 进入windows核心态的通用方法
- · 2003-10-29 致Borland C++开发者社群的公开信 -- J.P. LeBlanc
- · Windows应用程序调试策略(一)
- · Windows应用程序调试策略(二)
- · VC常见入门问题总结(二)
- · Windows GDI中的坐标系一文所涉及的代码
- · C++常用排序算法
- · 常用查找算法
- · 关于字符串的用法和转换补遗:
- · 办公之星控件OA应用开发方案
- · 如何在程序中实现关联指定的文件类型
- · 你需要virtual析构函数吗
- · 平台+插件源代码最新地址
- · GIS在商业活动中的应用
- · Win32 环境下的堆栈(一)
- · 常用查找算法
- · 软件工具——字符串过滤器
- · C++初学解惑(5)——构造函数(中)
- · 浅谈 wxWindows FrameWork
- · CString实现原理简单介绍!
- · 在NT中直接访问物理内存
- · 自学WinSocket I/O Methods
- · 树状控件的应用(选择出阵武将)
- · Step By Step 可连接对象与接受器实现
- · ffdff000 处的结构 KPCR
- · 矩形体排样问题
- · Socket传输文件示例(上)
- · Socket传输文件示例(下)
- · 关于在XtremeToolkit2.0环境下使用中文
- · 使用虚列表和自画实现文件夹的缩略图显示
- · 重载赋值运算符
- · 瞎侃编译和解释
- · 用拷贝钩子实现对文件夹的监控
- · sniffer技术原理及应用,包括编程方法和工具使用
- · 如何编程动态改变IE的代理服务器设置, 并且使之马上生效!
- · 用VC6编写注册表管理程序
- · 用VC6编写注册表管理程序(二)
- · 用VC6编写注册表管理程序(三)
