欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android开发中计算器的sin、cos及tan值计算问题分析

程序员文章站 2023-11-24 18:55:52
本文实例讲述了android开发中计算器的sin、cos及tan值计算问题。分享给大家供大家参考,具体如下: 接到一个需求 :要求计算器sin90=1,拿到知道很疑问 难...

本文实例讲述了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了!

ps:这里再为大家推荐几款计算工具供大家进一步参考借鉴:

在线一元函数(方程)求解计算工具:

科学计算器在线使用_高级计算器在线计算:

在线计算器_标准计算器:

更多关于android相关内容感兴趣的读者可查看本站专题:《android开发入门与进阶教程》、《android基本组件用法总结》、《android视图view技巧总结》、《android布局layout技巧总结》及《android控件用法总结

希望本文所述对大家android程序设计有所帮助。