js简易计算器 实现输入符号弹出错误提示的功能。这个用的是正则位运算计算器,不提示。帮忙将我的代码改下。

您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
 JavaScript计算器(包含累计与显示功能).doc 14页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
下载提示
1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。
2.该文档所得收入(下载+内容+预览三)归上传者、原创者。
3.登录后可充值,立即自动返金币,充值渠道很便利
需要金币:200 &&
你可能关注的文档:
··········
··········
计算器的逻辑对于新手而言比较复杂!新手学习JavaScript,很多代码重用,有很强的改进空间,不过这很适合新手,注释比较全面(基本上每句代码后都有注释);首先是js部分(3.js)varnum=0,result=0,numshow=&0&;varoperate=0;//判断输入状态的标志varcalcul=0;//判断计算状态的标志varquit=0;//防止重复按键的标志varzero_//&0&判断防止重复按&0&varend_num=&undefined&;//保留最后一个出现的值varljs_//累加数varfh_//最后的符号//数字的输入functioncommand(num){varstr=String(document.calculator.numScreen.value);//获得当前显示数据varstr1=String(document.calculator.onshow.value);str=(str!=&0&)?((operate==0)?str:&&):&&;//如果当前值不是&0&,且状态为0,则返回当前值,否则返回空值;str=str+String(num);//给当前值追加字符document.calculator.numScreen.value=//刷新显示operate=0;//重置输入状态quit=0;//重置防止重复按键的标志document.getElementById(&textShow&).value+=//写入显示框textShowsplitLastNum(document.calculator.onshow.value);//用于更新累加数(ljs_num)}//双&00&的输入functiondzero(){ varstr1=String(document.calculator.onshow.value);//获取显示框的值varstr=String(document.calculator.numScreen.value);//获取当前(numshow)显示的值str=(str!=&0&)?((operate==0)?str+&00&:&0&):&0&;//如果当前值不是&0&,且状态为0,则返回当str+&00&,否则返回&0&;document.calculator.numScreen.value=//更新numshow的值str=str+&00&;//刷新显示operate=0;//重置操作quit=0;//重置按键操作if(str1&&typeof(str1)!=&undefined&&&str1!=0){//判断显示栏是否有值 vararray=str1.split(fh_str);//用最后保留的符号拆分成数组 if(array!=null&&array.length&0){//取数组的最后一个子字符串
zero_pd=array[array.length-1];
varstr3=zero_pd.split(&&);//将子字符串拆分成字符
for(i=0;i&str3.i++){//遍历字符
vartype=&^-?\\d+$&;//定义类型type,值为判断是否为整数的正则表达式
varre=newRegExp(type);//匹配字符串if(str3[i]==&.&||str3[i].match(re)!=null){//判断str3中是否存在数字或者&.& document.getElementById(&textShow&).value+=&00&;//文本框(textshow)中加入&00& splitLastNum(document.calculator.onshow.value);//将值加入累加数并刷新
}}}}//&0&输入functionzero(){ varstr1=String(document.calculator.onshow.value);//获
正在加载中,请稍后...3539人阅读
C#应用(1)
使用正则表达式实现简易表达式计算器
由于我是做工程的,在实际使用中经常要对复杂公式进行计算,觉得使用
计算器非常不方便,也容易出错,而
用于小型的计算太浪费(主要是启动比较慢,而且不是所有地方都有),因此决定自己写一个表达式计算器进行使用。在写计算器的过程中,研究了
的正则表达式系统,略有心得。将其写出来与大家分享。
注:实际完成的表达式计算器可在我的
共享上下载,基于了
版。同时也提供了一个
.NET 2.0 Compact
的版本,可以用于
手机,实测在
Windows Mobile 6.1
Windows Mobile 6.5
上运行正常。
在工程应用中,用到最多的就是整数的位运算,与或非异或移位等操作非常频繁,且经常会有连续操作。特别是在通信控制中,经常使用的校验(采用累加或异或的方式),要计算也较多,因此首先考虑了整数的表达式计算,后续考虑了双精度数据的计算。
.NET Framework
正则表达式概述(
本节内容来自
Microsoft MSDN
正则表达式提供了功能强大、灵活而又高效的方法来处理文本。正则表达式的全面模式匹配表示法使您可以快速分析大量文本以找到特定的字符模式;验证文本以确保它匹配预定义的模式(如电子邮件地址);提取、编辑、替换或删除文本子字符串;将提取的字符串添加到集合以生成报告。对于处理字符串或分析大文本块的许多应用程序而言,正则表达式是不可缺少的工具。
正则表达式的工作方式
使用正则表达式处理文本的中心构件是正则表达式引擎,该引擎在
.NET Framework
对象表示。
使用正则表达式处理文本至少要求向该正则表达式引擎提供以下两方面的信息:
要在文本中标识的正则表达式模式。
.NET Framework
中,正则表达式模式用特殊的语法或语言定义,该语法或语言与
正则表达式兼容,并添加了一些其他功能,例如从右到左匹配。有关更多信息,请参见
要为正则表达式模式分析的文本。
类的方法使您可以执行以下操作:
方法确定输入文本中是否具有正则表达式模式匹配项。
方法验证文本的示例,请参见
方法检索匹配正则表达式模式的一个或所有文本匹配项。
第一个方法返回提供有关匹配文本的信息的
第二个方法返回
对象,该对象对于在分析的文本中找到的每个匹配项包含一个
方法替换匹配正则表达式模式的文本。
方法更改日期格式和移除字符串中的无效字符的示例,请参见
正则表达式使用请参见
Microsoft MSDN
整数表达式运算的实现
首先要确定整数表达式运算需要实现哪一些功能。根据实际情况,当前确定整数表达式运算至少应该支持如下功能:
可进行四则运算(加法
可进行求模(余)操作(
可进行位运算(取反
可进行移位操作(左移
可进行部分函数运算(符号
运算之间要按照优先级进行;
提升运算优先级
进制混用(
进制,否则
先考虑没有括号的情况。为了简化程序设计,考虑识别计算过程按如下步骤进行:
将整个长表达式按照优先级取出优先级最高的基本表达式元素;
对该最基本元素求结果,并用结果替代长表达式中的元素以简化表达式;
进行迭代直到剩下最后一个基本表达式元素;
计算该元素的值,即为整个表达式的运算结果。
以下以一个实例说明计算流程。假设要计算
,表达式简化为
,表达式简化为
,即得出最终结果。
再考虑有括号的情况。对于有括号的表达式,由于括号优先级最高,可以先将括号中的子串取出,按照上述流程计算出子串的数据,再替换(若是函数则要先计算)子串数据,逐次迭代最终得到结果。
获取一个数(
进制)的正则表达式:
要获取一个普通的
进制整数,如
,采用正则表达式:
要获取一个带有
进制整数(
,采用正则表达式:
?(?=0x)0x[0-9a-f]
该数据可能有正负符号前导,因此采用:
综上所述,
(?&num&[/+/-]?(?(?=0x)0x[0-9a-f]+|/d+))
可以用来捕获一个带有前导符号的
基本表达式元素的计算
首先考虑只有一个运算符的形式
,先按照运算符优先级将相同优先级的运算符声明每个正则表达式(用行隔开了运算符和数据的捕获,下同):
Regex RegxUnary = new Regex(
@&(?&op&[~])+?
(?&num&[/+/-]?(?(?=0x)0x[0-9a-f]+|/d+))&,
RegexOptions.IgnoreCase
| RegexOptions.ExplicitCapture);
Regex RegxMultDiv =
new Regex(
@&(?&num1&[/+/-]?(?(?=0x)0x[0-9a-f]+|/d+))
(?&op&[/*///%])
(?&num2&[/+/-]?(?(?=0x)0x[0-9a-f]+|/d+))&,
RegexOptions.IgnoreCase
| RegexOptions.ExplicitCapture);
RegxAddSub = new Regex(
@&(?&num1&[/+/-]?(?(?=0x)0x[0-9a-f]+|/d+))
(?&op&[/+/-])
(?&num2&[/+/-]?(?(?=0x)0x[0-9a-f]+|/d+))&,
RegexOptions.IgnoreCase
| RegexOptions.ExplicitCapture);
然后是移位(命名为
),最后是其他位操作(与
异或)(命名为
这些正则表达式的写法都相同,此处不再一一列举。
使用正则表达式匹配出表达式以后,可以通过
对象获取操作符和操作数,即可以求出结果。
不带括号的长表达式计算
在实际使用中,仅仅只有一个基本表达式是不可能的,因此计算器一定要匹配连续运算符,如:
1+2*3-4%5*6/7&&~8
此时,用上述的正则表达式匹配时,第一个问题就是:如何区别一个数字前面的
符号是表示正负还是一个运算符?简单来讲,对于
两个表达式,第一个表达式中的
为减法运算,而第二个表达式中的
)。如果用前面的正则表达式进行匹配,则这两个表达式首先匹配的结果都是
,而这个结果对于第一个表达式来讲是错误匹配。为了解决该问题,必须对前面所采用的正则表达式进行修改。
增加一个顶格判定,因为如果一个表达式以
开头,则这个
一定表示正或负,而不是运算符。将
(?&num1&[/+/-]?(?(?=0x)0x[0-9a-f]+|/d+))
^(?&num1&[/+/-]?(?(?=0x)0x[0-9a-f]+|/d+))
这样即可以避免将
的第一个表达式匹配为
。但更改以后
无法匹配出表达式
应该还有另一种可能,为
(?&=([,/+/-/%&/|/^]|&&|&&))(?&num1&[/+/-]?(?(?=0x)0x[0-9a-f]+|/d+))
(上述表达式仅对应乘除余)
之前有逗号、
的时候,该
为正负号而非运算符。
因此,乘除余匹配的正则表达式变更为:
Regex RegxMultDivMod
= new Regex(
@&(^(?&num1&[/+/-]?(?(?=0x)0x[0-9a-f]+|/d+))
|(?&=([,/+/-/%&/|/^~]|&&|&&))(?&num1&[/+/-]?(?(?=0x)0x[0-9a-f]+|/d+)))
(?&op&[/*///%])
(?&num2&[/+/-]?(?(?=0x)0x[0-9a-f]+|/d+))&,
RegexOptions
.IgnoreCase
| RegexOptions
.ExplicitCapture);
根据相同原理,修改前面的所有基本元素表达式。其中,
前出现的符号与优先级有关,即应该包含所有比本正则表达式运算符的优先级要低的其他运算符(包括逗号)。
当所有匹配的正则表达式都修改完成后,即可以进行不带括号的长表达式进行处理了。处理的顺序按照优先级的顺序。处理函数如下:
CalcSub(string
&&&&&&&&&&&
&&&&&&&&&&&
StringBuilder
StringBuilder
&&&&&&&&&&&
&&&&&&&&&&&
.ToString());
&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&&&&&
获取操作数和操作符,并进行计算
&&&&&&&&&&&&&&&
用计算结果替换表达式
&&&&&&&&&&&&&&&
再次执行匹配
&&&&&&&&&&&
&&&&&&&&&&&
RegxMultDivMod
.ToString());
&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&&&&&
操作,省略
&&&&&&&&&&&
&&&&&&&&&&&
RegxAddSub
.ToString());
&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&&&&&
操作,省略
&&&&&&&&&&&
&&&&&&&&&&
= RegxShift
.ToString());
&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&&&&&
操作,省略
&&&&&&&&&&&
&&&&&&&&&&&
.ToString());
&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&&&&&
操作,省略
&&&&&&&&&&&
.ToString();
到目前为止,已经可以很好的计算没有括号的整数长表达式了。下一步的工作是考虑函数的计算。根据先前设定,整数表达式运算需要支持的函数包括符号
等,这些函数中,有的函数只有一个参数,如
,而有的函数需要两个参数,如
。为了适应这两种情况,定义两个函数正则表达式,分别匹配这两种不同类型的函数。
RegxFunction
@&(?&func&abs|sign)
/((?&num&[/+/-]?(?(?=0x)0x[0-9a-f]+|/d+))/)&
RegexOptions
.IgnoreCase
| RegexOptions
.ExplicitCapture);
RegxFunction2
@&(?&func&pow|max|min)
/((?&num1&[/+/-]?(?(?=0x)0x[0-9a-f]+|/d+)),
(?&num2&[/+/-]?(?(?=0x)0x[0-9a-f]+|/d+))/)&
RegexOptions
.IgnoreCase
| RegexOptions
.ExplicitCapture);
进行函数计算时,首先,将函数括号内的表达式按照
节进行计算,并得到最终仅剩下不含表达式的基本数值形式,然后再使用函数正则表达式进行匹配。如
max(3*4,1&&3)
先将()内的表达式化简为(
),再计算
复合表达式计算
好了,目前表达式计算器已经可以较好的工作了,但是针对超复杂的表达式还无能为例,例如,要计算
max(abs(7&&2+3*(4-1)^3),min(18*sign(0xAA-0x55),0x35^0x18^(~0x20&0xFF)))+100
实际上,任何一个复杂表达式都可以化简为简单表达式的组合,根据这个原理,采用如下方式进行计算:
令整个表达式为
先取出最右边的一个括号内的表达式(设为
节的定义进行计算;
中是否有一个参数的函数,若有则进行计算;
是否有两个参数的函数,若有则进行计算;
中存在有效匹配,则重复进行
操作,直到没有有效匹配
中都没有任何有效匹配,则证明表达式
已计算到最简状态,此时移除
外的括号,并寻找表达式
中的下一个最右边的括号中的表达式。
若寻找到含有括号的最右边表达式,则重复进行
如果已经没有括号了,证明表达式已经到达最基本状态,此时执行
即可得出最终结果。
对于为何要从最右侧开始的括号开始取子表达式,主要原因是因为好定位。因为最后一个左括号其匹配的右括号一定是在该左括号后的第一个右括号。
处理函数如下:
Calc(string
&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&
StringBuilder
StringBuilder
&&&&&&&&&&&
.Replace(& &
&&&&&&&&&&&
-1, rightPos
&&&&&&&&&&&
.ToString()
.LastIndexOf('('
&&&&&&&&&&&
&&&&&&&&&&&&&&&
.ToString()
.IndexOf(')'
&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&&&&&
.ToString()
.Substring(leftPos
1, rightPos
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
(CalcSub(sub, out
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
.Replace(sub, res, leftPos, rightPos
- leftPos);
&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
(CalcFunc(sb))
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
(CalcFunc2(sb))
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&
.Remove(rightPos,
&&&&&&&&&&&&&&&&&&&&&&&
.Remove(leftPos,
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
.ToString()
.LastIndexOf('('
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
.ToString()
.IndexOf(')'
&&&&&&&&&&&
CalcSub(sb
.ToString(), out
&&&&&&&&&&&
GetIntValue(res);
一点小提升
事实上,整数表达式计算器已经基本上可以很正确的计算出所有表达式了,但是还是存在一些不太人性化的地方。主要问题是没有异常处理操作,也没有表达式错误提示。
考虑以下表达式:假设由于输入错误,输入了
。对于该表达式目前的表达式计算器会得出一个很莫名其妙的结果
。事实上,该问题是将
的计算结果去掉括号后,与
进行了连接操作,这根本不是我们希望得到的结果。实际上,对于这种错误表达式,我们希望提示一个错误,并告知在
之间缺少一个运算符。同样,这个问题可以使用正则表达式来解决。可以先用正则表达式来匹配这些不合理的表达式,并将其筛选出来,以提醒用户表达式输入有误。
另外,再考虑一个表达式
)。实际上是一个很简单的问题,由于出现了
除,在计算
时得到的返回结果为正无穷大(或者是非数字),此时如果还有未计算完的表达式,则运算过程将抛出一个异常。因此,应该设置一个错误追踪功能,当在计算过程中发生异常时,要提示用户在哪个地方发生了异常。
笔者实现的表达式计算器中考虑了该问题,当输入错误的表达式时,会给出一个提示,指出错误的为止;当出现左右括号数量不一致时,会提示用户数量不一致。
浮点表达式运算的实现
浮点表达式的计算与整数表达式运算的处理方式大致相同。其差别主要在于:
浮点表达式计算不支持
进制数,不支持位操作;
浮点表达式计算支持更多函数的计算,包括开方、三角函数、对数等运算;
表示自然对数,可以用
表示圆周率;
支持科学计数法输入,如
浮点数的匹配采用以下正则表达式:
(?&num&[/+/-]?/d+(/./d+)?(e[/+/-]?/d+)?)
浮点运算实现的一个有趣的问题在于
字母的使用。
为底的幂函数;
表示科学计数法。实际上,要识别指示
字母,简单的使用
即可以匹配。
因为浮点运算与整数运算的处理方式基本相同,因此此处不再列出具体的浮点运算实现。
笔者的表达式计算器执行程序可以从笔者的
网盘上下载。若有需要完整的源代码,
与笔者联系。欢迎各位提出宝贵的意见和建议。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:5069次
排名:千里之外js正则实现的密码框简单制作,还可以替换成自己想用得符号-表单特效
密码框简单制作,还可以替换成自己想用得符号. &style type=&text/css&& #c { position: } #a { position: left: 0; top: 0; font-size: 12 font
密码框简单制作,还可以替换成自己想用得符号. &style type="text/css"& #c { position: } #a { position: left: 0; top: 0; font-size: 12 font-family: 宋体; } #b { position: left: 0; top: 0; font-size: 12 font-family: 宋体; -moz-opacity:0;opacity: 0;filter: alpha(opacity=0); } &/style& &body& &div id="c"& &input id="a" /& &input id="b" onkeyup="document.getElementById('a').value=this.value.replace(/./g,'*');" /& &/div&

我要回帖

更多关于 双浮点运算计算器在线 的文章

 

随机推荐