Android開(kāi)發(fā)中計(jì)算器的sin、cos及tan值計(jì)算問(wèn)題分析
本文實(shí)例講述了Android開(kāi)發(fā)中計(jì)算器的sin、cos及tan值計(jì)算問(wèn)題。分享給大家供大家參考,具體如下:
接到一個(gè)需求 :要求計(jì)算器sin90=1,拿到知道很疑問(wèn) 難道不等于一么?測(cè)試了四五個(gè)手機(jī) ,有的滿足,有的sin90=0.8939…。查了api文檔后發(fā)現(xiàn) jdk中Math.sin/cos/tan ()求值采用弧度值,目前覺(jué)大部分手機(jī)計(jì)算器 如果滿足sin(90)=1就不會(huì)滿足sin(pi/2)=1,因?yàn)槠渌惴ㄈ绻D(zhuǎn)換弧度值(x/180*pi).當(dāng)輸入弧度值算時(shí)會(huì)變?yōu)閟in(弧度值/180*pi)使結(jié)果錯(cuò)誤。實(shí)現(xiàn)計(jì)算器算法使可分sin中是否含pi來(lái)進(jìn)行不同的處理
我的解決辦法如下:
修改代碼途徑
\packages\apps\Calculator\src\com\android\calculator\CalculatorExpressionEvaluator.java
部分源代碼:
輸入的算式經(jīng)過(guò)這個(gè)方法傳入,然后轉(zhuǎn)過(guò)另一個(gè)類求出計(jì)算值,該類在位置org.javia.arity.Symbols;(被封裝打不開(kāi),只能修改代入值)
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”, 如果有,在每個(gè)該字符后面添加字符串”pi/180*”
所以我在代入前加了一個(gè)正則表達(dá)式過(guò)濾
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 { /************** 添加的過(guò)濾代碼 ***********/ 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了!
PS:這里再為大家推薦幾款計(jì)算工具供大家進(jìn)一步參考借鑒:
在線一元函數(shù)(方程)求解計(jì)算工具:
http://tools.jb51.net/jisuanqi/equ_jisuanqi
科學(xué)計(jì)算器在線使用_高級(jí)計(jì)算器在線計(jì)算:
http://tools.jb51.net/jisuanqi/jsqkexue
在線計(jì)算器_標(biāo)準(zhǔn)計(jì)算器:
http://tools.jb51.net/jisuanqi/jsq
更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android開(kāi)發(fā)入門(mén)與進(jìn)階教程》、《Android基本組件用法總結(jié)》、《Android視圖View技巧總結(jié)》、《Android布局layout技巧總結(jié)》及《Android控件用法總結(jié)》
希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。
- android實(shí)現(xiàn)簡(jiǎn)易計(jì)算器
- Android開(kāi)發(fā)實(shí)現(xiàn)的標(biāo)準(zhǔn)體重計(jì)算器功能示例
- android計(jì)算器簡(jiǎn)單實(shí)現(xiàn)代碼
- 簡(jiǎn)單實(shí)現(xiàn)Android計(jì)算器功能
- Android計(jì)算器編寫(xiě)代碼
- 從零開(kāi)始學(xué)android實(shí)現(xiàn)計(jì)算器功能示例分享(計(jì)算器源碼)
- Android計(jì)算器簡(jiǎn)單邏輯實(shí)現(xiàn)實(shí)例分享
- android計(jì)算器代碼示例分享
- android計(jì)時(shí)器,時(shí)間計(jì)算器的實(shí)現(xiàn)方法
- Android Studio實(shí)現(xiàn)簡(jiǎn)易計(jì)算器
相關(guān)文章
Android編程使用sax解析xml數(shù)據(jù)的方法詳解
這篇文章主要介紹了Android編程使用sax解析xml數(shù)據(jù)的方法,結(jié)合實(shí)例形式詳細(xì)分析了Android使用sax解析xml數(shù)據(jù)的操作步驟及界面布局、單元測(cè)試等相關(guān)操作技巧,需要的朋友可以參考下2017-07-07Android開(kāi)發(fā)教程之如何屏蔽View的重復(fù)點(diǎn)擊
這篇文章主要給大家介紹了關(guān)于Android開(kāi)發(fā)教程之如何屏蔽View的重復(fù)點(diǎn)擊的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-09-09Android開(kāi)發(fā)vsts?agent支持自定義task過(guò)程詳解
這篇文章主要介紹了Android開(kāi)發(fā)vsts?agent支持自定義task過(guò)程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04Android compose氣泡升起和水滴下墜動(dòng)畫(huà)實(shí)現(xiàn)示例
這篇文章主要為大家介紹了Android compose氣泡升起和水滴下墜動(dòng)畫(huà)實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01Android之PreferenceActivity應(yīng)用詳解(2)
看到很多書(shū)中都沒(méi)有對(duì)PreferenceActivity做介紹,而我正好又在項(xiàng)目中用到,所以就把自己的使用的在這總結(jié)一下,也方便日后查找2012-11-11Android自定義PopupWindow實(shí)現(xiàn)炫酷的IOS對(duì)話框效果
這篇文章主要給大家介紹如何在android中實(shí)現(xiàn)高仿ios對(duì)話框效果,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2018-05-05EditText監(jiān)聽(tīng)方法,實(shí)時(shí)的判斷輸入多少字符
在EditText提供了一個(gè)方法addTextChangedListener實(shí)現(xiàn)對(duì)輸入文本的監(jiān)控。本文分享了EditText監(jiān)聽(tīng)方法案例,需要的朋友一起來(lái)看下吧2016-12-12Android view更改背景資源與padding消失的問(wèn)題解決辦法
這篇文章主要介紹了Android view更改背景資源與padding消失的問(wèn)題解決辦法的相關(guān)資料,需要的朋友可以參考下2017-04-04