我想编写一个将字符串转换为 BigDecimal 的解析器。 要求100%准确。 (嗯,我现在编程是为了好玩。所以我宁愿要求它......;-P)
所以我想出了这个程序:
public static BigDecimal parse(String term) {
char[] termArray = term.toCharArray();
BigDecimal val = new BigDecimal(0D);
int decimal = 0;
for(char c:termArray) {
if(Character.isDigit(c)) {
if(decimal == 0) {
val = val.multiply(new BigDecimal(10D));
val = val.add(new BigDecimal(Character.getNumericValue(c)));
} else {
val = val.add(new BigDecimal(Character.getNumericValue(c) * Math.pow(10, -1D * decimal)));
decimal++;
}
}
if(c == '.') {
if(decimal != 0) {
throw new IllegalArgumentException("There mustn't be multiple points in this number: " + term);
} else {
decimal++;
}
}
}
return val;
}
所以我尝试了:
parse("12.45").toString();
我预计它是12.45
。相反,它是 12.45000000000000002498001805406602215953171253204345703125
。我知道这可能是由于二进制表示的限制。但我该如何解决这个问题呢?
注意:我知道您可以使用new BigDecimal("12.45");
。但这不是我的观点 - 我想自己写它,无论这可能有多愚蠢。
最佳答案
是的,这是由于二进制表示的限制。任何 10 的负幂都不能精确地表示为 double
。
要解决此问题,请将所有 double
算术替换为所有 BigDecimal
算术。
val = val.add(
new BigDecimal(Character.getNumericValue(c)).divide(BigDecimal.TEN.pow(decimal)));
这样我得到12.45
。
关于java - 由于 BigDecimals 中的二进制表示形式导致数字不准确。我该如何解决它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55752888/