1、环境准备
- windows 7,8,10,11操作系统
- ahk 2.x_64位
2、使用方式
在运行框中输入带有 +(加法), -(减法), *(乘法), /(除法), **(幂),^(幂), %(模),()括号优先运算的表达式,都认为是数学表达式!
同时数字支持 ,k(千) ,w(万),y(亿)缩写 ,大小写不敏感
支持连续计算,计算出的结果可以继续使用运算符再计算!!
所有运算默认保留最多三位小数。
如果计算结果不准确会用约等于“≈”表示
sqrt 开平方根,单独使用,不能和上面表达式混用
- 输入win+R打开windows运行框
- 在运行框中输入:((100-90)^2+100)/10*5 ,输出:“100”
- 在运行框中输入:500w*2k/100 ,输出:“1亿”
- 在运行框中输入:100+2=102/2 ,输出 “51” 在上述操作中先计算100+2输出结果后,我们可以继续在后面继续运算 /2 ,会把上次结果当做下次计算的输入、
- 在运行框中输入:sqrt 100 ,输出10
- 表达式按== 触发结果
3、演示

4、代码
#HotIf winActive("运行") and winActive("ahk_class #32770")
#MaxThreadsPerHotkey 10
;在运行框中执行强大的计算功能,包括数学运算等
:*?:==::{try{rawText:=ControlGetText("Edit1","A") ;fullResult:=runbox.calculateExpression(rawText)if fullResult{ControlsetText(fullResult,"Edit1","A")}ControlSend("{END}","Edit1","A")}
}
#HotIf
;==========================================================================================================系统快捷键映射
;执行各种运算取值
class runbox
{;执行比表达式计算,"==" 触发,callflag是其他函数调用该方法static calculateExpression(rawstr,callflag:=0){;计算数学表达式if (result:=this.mathExpression(rawStr)){fulltxt:=rawStr . resultreturn result};计算平方根if inStr(rawStr,"sqrt ")==1{str:=Trim(Ltrim(rawStr,"sqrt"))result:=ak.get_bignumber(sqrt(str),3,0) ;该函数自带 = 或者 ≈fulltxt:=rawStr . resultreturn fulltxt}};计算数学表达式+,- ,x ,/ % ** 操作,支持括号,支持k(千),w(万),y(亿)static mathExpression(str){;计算数学表达式str2:=RegExReplace(str,"[abcdefghijlmnopqrstuvxzABCDEFGHIJLMNOPQRSTUVXZ]+","")if str!=str2returnif(InStr(str, "+") or InStr(str, "-") or InStr(str, "*") or InStr(str, "/")or InStr(str, "%") or InStr(str, "**")or InStr(str, "=") or InStr(str,"≈")or InStr(str, "^")){str:=InStr(str, "=")>0 ? ak.getSuffix(str,"="):str ;使连续计算成为可能str:=InStr(str,"≈")>0 ? ak.getSuffix(str,"≈"):str ;连续计算约等于str:=RegExReplace(str,"\s+","") ;缩紧字符串if inStr(str,"y") or inStr(str,"w") or inStr(str,"k")char_flag:=1str2:=ak.set_bignumber(str) ;处理字符y,w,kresult:=ak.polish_notation(str2) ;用逆波兰表达式计算值result:=ak.get_bignumber(result,3,char_flag??0) ;保留三位小数fulltxt:=str . result ;result中有等号return fulltxt}}
}
;==========================================================================================================系统快捷键映射
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ak工具类class
class ak
{;从路径中获取文件名或者是后缀 path:路径 ,separator 分隔器static getSuffix(path,separator:="\"){return inStr(path,separator)?SubStr(path,this.getStrLastIndex(path,separator)?this.getStrLastIndex(path,separator)+1:strLen(path)):path};Fucn 逆波兰表达式计算 + - x ÷ 幂(**/^) 模(%) expression:数学表达式可以带括号;参考:https://blog.csdn.net/assiduous_me/article/details/101981332static polish_notation(expression){operator_list:=Map("+",0,"-",0,"*",0,"`/",0,"%",0,"^",0) ;注意list的haskey操作只是检测索引operatorlevel_map:=Map("(",0,"+","1","-",1,"*",2,"/","2","%",2,"^",3,")",4)operator_map:=Map("+","add","-","sub" ,"*","multi","/","divi","%","mod2","^","pow")expression:=strReplace(strReplace(RegExReplace(trim(expression),"\s+",""),"**","^") ,"(-","(0-")expression:=inStr(expression,"-(")==1?strReplace(this.insertStrAt(expression,this.mirrorSymbolIndex(expression,"(",")"),")"),"-(","(0-("):expression;①.获取一个中缀表达式集合类似 100+2 -> ["100","+","2"]middlefix_list:=[],fix:=""Loop parse,expression{current_value:=A_LoopFieldif(operatorlevel_map.has(current_value)){tmp:=""!=fix?middlefix_list.push(fix):""middlefix_list.push(current_value)fix:=""}else fix:=fix . current_value}tmp2:=fix!=""?middlefix_list.push(fix):""if(middlefix_list[1]="-"){ ;处理开头为负数middlefix_list.insertAt(1,"(")middlefix_list.insertAt(2,"0")middlefix_list.insertAt(5,")")};②.转换为后缀表达式(逆波兰表达式)operator_stack:=[] ,suffix_list:=[],number_stack:=[]for index ,currentElmt in middlefix_list{if(operator_list.has(currentElmt)){while(operator_stack.length>0 && operatorlevel_map.get(operator_stack.get(operator_stack.Length))>=operatorlevel_map.get(currentElmt))suffix_list.push(operator_stack.pop())operator_stack.push(currentElmt)}else if(currentElmt=="(")operator_stack.push("(")else if(currentElmt==")"){while(operator_stack.length>0 && operatorlevel_map.get(operator_stack.get(operator_stack.length))>operatorlevel_map.get("("))suffix_list.push(operator_stack.pop())if(operator_stack.length>0)operator_stack.pop()}elsesuffix_list.push(currentElmt)}while(operator_stack.length>0)suffix_list.push(operator_stack.pop());③.计算表达式最终的值,规则数字入栈,操作符就出栈两个元素计算值并把结果入栈for key,opertor_or_number in suffix_list{if(operator_list.has(opertor_or_number)){number2:=number_stack.pop(),number1:=number_stack.pop()tmpObj:={add:number1+number2,sub:number1-number2,multi:number1*number2,pow:number1**number2}T1:=opertor_or_number=="/"?(tmpObj.divi:=number1/number2):"" ;除法容易引发除0异常T2:=opertor_or_number=="%"?(tmpObj.mod2:=mod(number1,number2)):"" ;取模容易引发除0异常number_stack.push(tmpObj.%operator_map.get(opertor_or_number)%)}elsenumber_stack.push(opertor_or_number)}return number_stack.pop()};Func 计算对称符号所在位置str:原字符串,firstIndex:左边符号所在位置,symbol:右边符号 返回右边符号在原字符串中索引 "-((10000+500)-500)/2" 返回18static mirrorSymbolIndex(str,Lsymbol,Rsymbol){flag:=false ,list:=[]Loop Parse ,str {if(Lsymbol==(sub:=subStr(Str,A_index,1))){list.push(sub)flag:=true}R:=Rsymbol==subStr(Str,A_index,1)?list.pop():""if(list.length==0 and flag)return A_index}return 0};Func 处理算式中含有k,w,y的,formula 表达式static set_bignumber(formula){formula:=RegExReplace(formula,"(\d*\.*\d*)k|K","($1*1000)") ;处理1kformula:=RegExReplace(formula,"(\d*\.*\d*)w|W","($1*10000)") ;处理 1wformula:=RegExReplace(formula,"(\d*\.*\d*)y|Y","($1*100000000)") ;处理1亿return formula};func 作用:处理大的数字,;参数:bigNumber数字类型的大数字,char_flag:0,1(是否带k,w,y), scale 数字类型保留几位小数;返回:返回字符串;msgBox % Round(100,2)static get_bignumber(bigNumber,scale:=0,char_flag:=1){;判断有几位小数index:=InStr(bigNumber,".")left :=index=0?strLen(bigNumber):InStr(bigNumber,".")-1unit:="",prefix:="="if char_flag{if(left==4) ;单位K{result:=Round(bigNumber/1000,scale)prefix:=(result==bigNumber/1000)?"=":"≈"unit:="k"}else if(left>4 && left <9) ;单位w{result:=Round(bigNumber/10000,scale)prefix:=(result==bigNumber/10000)?"=":"≈"unit:="w"}else if(left>=9) ;单位亿{result:=Round(bigNumber/100000000,scale)prefix:=(result==bigNumber/100000000)?"=":"≈"unit:="亿"}else{ ;小于1kresult:=Round(bigNumber,scale)prefix:=(result==bigNumber)?"=":"≈"}}else{ ;正常表示方式result:=Round(bigNumber,scale)prefix:=(result==bigNumber)?"=":"≈"}result:=RegExReplace(result,"\.0+$","") ;去掉 2.000这样式的if(InStr(result,".")>0)result:=RegExReplace(result,"0+$","")return prefix . result . unit};找到字符最后一次出现的位置 str:原字符串,needle:需要寻找的字符串static getStrLastIndex(str,needle){loop len:=strLen(str){if(SubStr(str, len-A_index+1,strLen(needle))==needle)return len-A_index+1}return 0}
}
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ak工具类class
5、总结
由于很多操作代码可以复用,单个功能代码臃肿,
完整功能参考:windows超级运行框-表达式计算(12)汇总
各位大佬觉得还可以怎么操作? 欢迎评论区留言讨论!