Android开发中计算器的sin、cos及tan值计算问题分析
本文实例讲述了Android开发中计算器的sin、cos及tan值计算问题。分享给大家供大家参考,具体如下:
接到一个需求:要求计算器sin90=1,拿到知道很疑问难道不等于一么?测试了四五个手机,有的满足,有的sin90=0.8939…。查了api文档后发现jdk中Math.sin/cos/tan()求值采用弧度值,目前觉大部分手机计算器如果满足sin(90)=1就不会满足sin(pi/2)=1,因为其算法如果转换弧度值(x/180*pi).当输入弧度值算时会变为sin(弧度值/180*pi)使结果错误。实现计算器算法使可分sin中是否含pi来进行不同的处理
我的解决办法如下:
修改代码途径
\packages\apps\Calculator\src\com\android\calculator\CalculatorExpressionEvaluator.java
部分源代码:
输入的算式经过这个方法传入,然后转过另一个类求出计算值,该类在位置org.javia.arity.Symbols;(被封装打不开,只能修改代入值)
publicvoidevaluate(Stringexpr,EvaluateCallbackcallback){ expr=mTokenizer.getNormalizedExpression(expr); //removeanytrailingoperators while(expr.length()>0&&"+-/*".indexOf(expr.charAt(expr.length()-1))!=-1){ expr=expr.substring(0,expr.length()-1); } /*try{ if(expr.length()==0||Double.valueOf(expr)!=null){ callback.onEvaluate(expr,null,Calculator.INVALID_RES_ID); return; } }catch(NumberFormatExceptione){ //exprisnotasimplenumber }*/ if(expr.length()==0){ callback.onEvaluate(expr,null,Calculator.INVALID_RES_ID); return; } try{ /*************代值的代码在这里**********/ doubleresult=mSymbols.eval(expr); if(Double.isNaN(result)){ callback.onEvaluate(expr,null,R.string.error_nan); }else{ /*Thearitylibraryusesfloatingpointarithmeticwhenevaluatingtheexpression leadingtoprecisionerrorsintheresult.ThemethoddoubleToStringhidesthese errors;roundingtheresultbydroppingNdigitsofprecision.*/ finalStringresultString=mTokenizer.getLocalizedExpression( Util.doubleToString(result,MAX_DIGITS,ROUNDING_DIGITS)); callback.onEvaluate(expr,resultString,Calculator.INVALID_RES_ID); } }catch(SyntaxExceptione){ callback.onEvaluate(expr,null,R.string.error_syntax); } }
我的解决思路是:
断某该字符串是否含有”sin(”,”cos(”,”tan(”字符,并且不含“sin(pi”,“cos(pi”,“tan(pi”,如果有,在每个该字符后面添加字符串”pi/180*”
所以我在代入前加了一个正则表达式过滤
publicvoidevaluate(Stringexpr,EvaluateCallbackcallback){ expr=mTokenizer.getNormalizedExpression(expr); //removeanytrailingoperators while(expr.length()>0&&"+-/*".indexOf(expr.charAt(expr.length()-1))!=-1){ expr=expr.substring(0,expr.length()-1); } /*try{ if(expr.length()==0||Double.valueOf(expr)!=null){ callback.onEvaluate(expr,null,Calculator.INVALID_RES_ID); return; } }catch(NumberFormatExceptione){ //exprisnotasimplenumber }*/ if(expr.length()==0){ callback.onEvaluate(expr,null,Calculator.INVALID_RES_ID); return; } try{ /**************添加的过滤代码***********/ expr=expr.replaceAll("(?<=(sin|cos|tan)[(])(?!pi)","pi/180*"); doubleresult=mSymbols.eval(expr); if(Double.isNaN(result)){ callback.onEvaluate(expr,null,R.string.error_nan); }else{ /*Thearitylibraryusesfloatingpointarithmeticwhenevaluatingtheexpression leadingtoprecisionerrorsintheresult.ThemethoddoubleToStringhidesthese errors;roundingtheresultbydroppingNdigitsofprecision.*/ finalStringresultString=mTokenizer.getLocalizedExpression( Util.doubleToString(result,MAX_DIGITS,ROUNDING_DIGITS)); callback.onEvaluate(expr,resultString,Calculator.INVALID_RES_ID); } }catch(SyntaxExceptione){ callback.onEvaluate(expr,null,R.string.error_syntax); } }
然后就能满足sin90=1了!
PS:这里再为大家推荐几款计算工具供大家进一步参考借鉴:
在线一元函数(方程)求解计算工具:
http://tools.jb51.net/jisuanqi/equ_jisuanqi
科学计算器在线使用_高级计算器在线计算:
http://tools.jb51.net/jisuanqi/jsqkexue
在线计算器_标准计算器:
http://tools.jb51.net/jisuanqi/jsq
更多关于Android相关内容感兴趣的读者可查看本站专题:《Android开发入门与进阶教程》、《Android基本组件用法总结》、《Android视图View技巧总结》、《Android布局layout技巧总结》及《Android控件用法总结》
希望本文所述对大家Android程序设计有所帮助。