我有一个来自 JEval 的输出操作,它是一个浮点不精确的字符串,类似于“1.56700000001”。我需要一些方法来保持最大精度但纠正浮点不精度。也许是一些有效的算法可以做出最准确的事情而不会出错。
如果我没记错的话,任何具有不精确二进制表示的双精度都将在长度() 18 的字符串中输出,精度 =(14 减 - 点字符 - 整数部分)。
因此,当字符串清楚地使用所有位而没有尾随零时,我们可以四舍五入到精度为 1(最后一个)的数字(因为 JEval 没有显示它们,这意味着当 length() == 18 时)。
唯一的问题是,如果原始字符串具有真正的预期完整值并且不需要四舍五入,在这种情况下,我们只会损失一位精度。您如何看待这种方法。这是更好的方法吗?
例如:
import java.math.BigDecimal;
import java.math.MathContext;
public class test {
private final static int THREESHOLD = 3; // num of decimals from which
// we consider that they represent a floating
// representation inaccuracy in case every double´s
//digit is used with no traliing zeroes ending
public static void main(String[] args){
String[] JEvalOutput = {"1.5555000000000001", //Rounding is needed
"234455555.29", //Rounding is not needed
"455656.45599999998", //Rounding is needed
"111132323232334.19", //Here there is a problem, should be rounded???
//Thats why we use THREESHOLD var, to distinguish when can we consider
"123456789012345678"};//Rounding is not needed
for (String aux : JEvalOutput){
int precision = aux.length()-(aux.contains(".")?1:0);
if (precision==17 && aux.contains(".") && aux.length()-aux.indexOf('.')-1 >THREESHOLD) precision--;
BigDecimal a = new BigDecimal(aux, new MathContext(precision)).stripTrailingZeros();
System.out.println(aux + " --> " + a.toPlainString()); //Only First and Third are rounded.
}
}
}
印刷:
1.5555000000000001 --> 1.5555
234455555.29 --> 234455555.29
455656.45599999998 --> 455656.456
111132323232334.19 --> 111132323232334.19 //If THREESHOLD was 1, then this would be 111(...)34.2
123456789012345678 --> 123456789012345678
有没有更清洁、最佳实践、专业的解决方案?