Android5.0 计算器计算结果不准确和结果末尾的多余的‘0’没有省略
一、问题的描述:
【测试步骤】
1.进入计算器
2.输入 100-99.9
3.查看计算结果
【测试结果】
1.结果为: 0.0999999999
【预期结果】
1.结果应为: 0.1
【测试步骤】
1.进入计算器
2.输入1000-999.9,查看结果是否为: 0.1
【测试结果】
1.结果显示为: 0.10000000
【预期结果】
1.计算结果小数点后多余的零应该省略。
二、解决方案:path:
package com.android.calculator2;
import java.util.Locale;//added
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;
private static final String NAN = "NaN";//added
public CalculatorExpressionEvaluator(CalculatorExpressionTokenizer 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(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
}
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.
/*add*/
String strResult = "";
for (int precision = MAX_DIGITS; precision > 6; precision--) {
strResult = tryFormattingWithPrecision(result, precision);
if (strResult.length() <= MAX_DIGITS) {
break;
}
}
/*end*/
final String resultString = mTokenizer.getLocalizedExpression(
/*Util.doubleToString(result, MAX_DIGITS, ROUNDING_DIGITS)*/strResult);//modified
callback.onEvaluate(expr, resultString, Calculator.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 errorResourceId);
}
/*added*/
private String tryFormattingWithPrecision(double value, int precision) {
// The standard scientific formatter is basically what we need. We will
// 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 && mantissa.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*/
}
原文:http://blog.csdn.net/lisineng/article/details/45191689