The Android5.0 calculator calculates inaccurate results and the excess ' 0 ' at the end of the result is not omitted
First, the description of the problem:
"Test Steps"
1. Enter the calculator
2. Enter 100-99.9
3. View Calculation results
"Test Results"
1. The result is: 0.0999999999
"Expected results"
1. The result should be: 0.1
"Test Steps"
1. Enter the calculator
2. Enter 1000-999.9 to see if the result is: 0.1
"Test Results"
1. The result is shown as: 0.10000000
"Expected results"
1. Calculation results The extra 0 after the decimal point should be omitted.
Second, the solution: path:
<span style= "FONT-SIZE:18PX;" >package Com.android.calculator2; <span style= "color: #ff0000;" >import java.util.locale;//added </span>import Org.javia.arity.symbols;import Org.javia.arity.syntaxexception;import Org.javia.arity.Util; public class Calculatorexpressionevaluator {private static final int max_digits = 12; private static final int rounding_digits = 2; Private final Symbols Msymbols; Private final Calculatorexpressiontokenizer Mtokenizer; <span style= "color: #ff0000;" >private static final String nan = "nan";//added</span> public calculatorexpressionevaluator (Calculatorex Pressiontokenizer tokenizer) {msymbols = new Symbols (); Mtokenizer = Tokenizer; } public void evaluate (Charsequence expr, Evaluatecallback callback) {Evaluate (expr.tostring (), callback); } public void evaluate (String expr, Evaluatecallback callback) {expr = Mtokenizer.getnormalizedexpression (exp R); 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} try {D ouble 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. <span style= "color: #ff0000;" >/*add*/String strresult = ""; for (int precision = max_digits; precision > 6; precision--) {strresult = Tryformattingwithprecision (re Sult, precision); if (Strresult.length () <= max_digits) {break; }}/*end*/</span> <span style= "color: #ff0000;" > Final String resultstring = mtokenizer.getlocalizedexpression (/*util.doubletostring (result, Max_digits, Rounding_digits) */strresult);//modified</span> callback.onevaluate (expr, resultString, Ca Lculator. INVALID_RES_ID); }} catch (Syntaxexception e) {callback.onevaluate (expr, null, r.string.error_syntax); }} public interface Evaluatecallback {public void onevaluate (string expr, string result, int errorresource ID); }</span>
<span style= "FONT-SIZE:18PX;" ><span style= "color: #ff0000;" >/*added*/Private String tryformattingwithprecision (double value, int precision) {//the standard Scie Ntific Formatter is basically what we need. We'll/start with what it produces and then massage it a bit. String result = String.Format (locale.us, "%" + max_digits + "." + precision + "G", value); if (Result.equals (NAN)) {//Treat Nan as Error return "Nan"; } String mantissa = result; String exponent = null; int e = result.indexof (' e '); if (E! =-1) {mantissa = result.substring (0, E); Strip "+" and unnecessary 0 ' s from the exponent exponent = result.substring (e + 1); if (Exponent.startswith ("+")) {exponent = exponent.substring (1); } exponent = string.valueof (Integer.parseint (exponent)); } else {mantissa = result; } int period = Mantissa.indexof ('. '); if (period = =-1) {period = Mantissa.indexof (', '); } if (Period! =-1) {//Strip trailing 0 ' s while (Mantissa.length () > 0 && Mantis Sa.endswith ("0")) {mantissa = mantissa.substring (0, Mantissa.length ()-1); } if (mantissa.length () = = period + 1) {mantissa = mantissa.substring (0, Mantissa.length ()-1) ; }} if (exponent! = null) {result = Mantissa + ' e ' + exponent; } else {result = Mantissa; } return result; }/*end*/</span>}</span>
Android5.0 Calculator calculation results inaccurate and redundant ' 0 ' at the end of the result does not omit the workaround