小編給大家分享一下Android開發(fā)中如何解決計算器的sin、cos及tan值計算問題,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
網(wǎng)站的建設(shè)創(chuàng)新互聯(lián)公司專注網(wǎng)站定制,經(jīng)驗豐富,不做模板,主營網(wǎng)站定制開發(fā).小程序定制開發(fā),H5頁面制作!給你煥然一新的設(shè)計體驗!已為成都房屋鑒定等企業(yè)提供專業(yè)服務(wù)。
具體如下:
接到一個需求 :要求計算器sin90=1,拿到知道很疑問 難道不等于一么?測試了四五個手機 ,有的滿足,有的sin90=0.8939…。查了api文檔后發(fā)現(xiàn) jdk中Math.sin/cos/tan ()求值采用弧度值,目前覺大部分手機計算器 如果滿足sin(90)=1就不會滿足sin(pi/2)=1,因為其算法如果轉(zhuǎn)換弧度值(x/180*pi).當(dāng)輸入弧度值算時會變?yōu)閟in(弧度值/180*pi)使結(jié)果錯誤。實現(xiàn)計算器算法使可分sin中是否含pi來進行不同的處理
我的解決辦法如下:
修改代碼途徑
\packages\apps\Calculator\src\com\android\calculator\CalculatorExpressionEvaluator.java
部分源代碼:
輸入的算式經(jīng)過這個方法傳入,然后轉(zhuǎn)過另一個類求出計算值,該類在位置org.javia.arity.Symbols;(被封裝打不開,只能修改代入值)
public void evaluate(String expr, EvaluateCallback callback) { expr = mTokenizer.getNormalizedExpression(expr); // remove any trailing operators 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 (NumberFormatException e) { // expr is not a simple number }*/ if (expr.length() == 0) { callback.onEvaluate(expr, null, Calculator.INVALID_RES_ID); return; } try { /*************代值的代碼在這里**********/ double result = mSymbols.eval(expr); if (Double.isNaN(result)) { callback.onEvaluate(expr, null, R.string.error_nan); } else { /* The arity library uses floating point arithmetic when evaluating the expression leading to precision errors in the result. The method doubleToString hides these errors; rounding the result by dropping N digits of precision.*/ final String resultString = mTokenizer.getLocalizedExpression( Util.doubleToString(result, MAX_DIGITS, ROUNDING_DIGITS)); callback.onEvaluate(expr, resultString, Calculator.INVALID_RES_ID); } } catch (SyntaxException e) { callback.onEvaluate(expr, null, R.string.error_syntax); } }
我的解決思路是:
斷某該字符串是否含有”sin( ” ,” cos( ” ,”tan(”字符,并且不含“sin(pi”,“cos(pi”,“tan(pi”, 如果有,在每個該字符后面添加字符串”pi/180*”
所以我在代入前加了一個正則表達式過濾
public void evaluate(String expr, EvaluateCallback callback) { expr = mTokenizer.getNormalizedExpression(expr); // remove any trailing operators 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 (NumberFormatException e) { // expr is not a simple number }*/ if (expr.length() == 0) { callback.onEvaluate(expr, null, Calculator.INVALID_RES_ID); return; } try { /************** 添加的過濾代碼 ***********/ expr=expr.replaceAll("(?<=(sin|cos|tan)[(])(?!pi)","pi/180*"); double result = mSymbols.eval(expr); if (Double.isNaN(result)) { callback.onEvaluate(expr, null, R.string.error_nan); } else { /* The arity library uses floating point arithmetic when evaluating the expression leading to precision errors in the result. The method doubleToString hides these errors; rounding the result by dropping N digits of precision.*/ final String resultString = mTokenizer.getLocalizedExpression( Util.doubleToString(result, MAX_DIGITS, ROUNDING_DIGITS)); callback.onEvaluate(expr, resultString, Calculator.INVALID_RES_ID); } } catch (SyntaxException e) { callback.onEvaluate(expr, null, R.string.error_syntax); } }
然后就能滿足sin90=1了!
看完了這篇文章,相信你對“Android開發(fā)中如何解決計算器的sin、cos及tan值計算問題”有了一定的了解,如果想了解更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!