温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Android开发中如何解决计算器的sin、cos及tan值计算问题

发布时间:2021-08-06 14:30:54 来源:亿速云 阅读:115 作者:小新 栏目:移动开发

小编给大家分享一下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;(被封装打不开,只能修改代入值)

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开发中如何解决计算器的sin、cos及tan值计算问题”有了一定的了解,如果想了解更多相关知识,欢迎关注亿速云行业资讯频道,感谢各位的阅读!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI