将“0.1”与.1进行比较

时间:2015-03-27 15:28:48

标签: java string double

我正在努力理解double的局限性。 0.1不能在有限系统中表示,因为它是重复的二进制值。但是,当我声明一个变量并给它0.1时,它仍然打印为0.1和 .0999999999999999,1.00000000000000001或类似的东西。但是,如果我添加一个0.1次十次的变量,它就会出现.9999999999999999,这就是我所期望的。

真正的问题是,当我知道这是不可能的时候,为什么它的打印精确到0.1?我有证据证明这不是真正的价值?

double d  = 0.1;
System.out.printf("%.16f\n",d);
System.out.printf("%.16f", d + d + d + d + d + d + d + d + d + d);

我要做的是将字符串文字与双重转换进行比较,以查看字符串中的值是否可以用double精确表示。例如:

“。5”== .5?预期答案:是的。

“。1”== .1?预期答案:否。

我正在尝试的比较是

number = new BigDecimal("0.1");
d = number.doubleValue();
if (number.compareTo(new BigDecimal(Double.toString(d))) == 0){
    // Doing something
}

任何帮助都可以理解为什么不能区分可以和不能用double表示的值。

1 个答案:

答案 0 :(得分:4)

要测试String是否代表double值,您可以执行以下操作:

private static boolean isADouble(String s) {
    return new BigDecimal(s).equals(new BigDecimal(Double.parseDouble(s)));
}

public static void main(String[] args) {
    System.out.println(isADouble("0.1"));  // false
    System.out.println(isADouble("0.5"));  // true
}

这是有效的,因为new BigDecimal(s)生成的BigDecimalString所代表的值完全相等,而new BigDecimal(Double.parseDouble(s))最接近的值 double到该值。

我将在最后解释为什么number.compareTo(new BigDecimal(Double.toString(d))) == 0 工作。

当你这样做时

double d = 0.1;
System.out.println(d);

您会得到答案0.1,因为d是与“真实”double最接近的0.1。 (double d = 0.1; 表示“将d设为最近double0.1”。撰写时

System.out.println(d + d + d + d + d + d + d + d + d + d);

您看到0.9999999999999999而不是1。您没有看到1的原因是因为double值比答案更接近于1(实际上一个值本身是double值)。没有理由为什么答案应该是最接近的double,因为d首先不是0.1(它只是靠近它),而且添加浮点数时会出现不准确的情况。

最后,number.compareTo(new BigDecimal(Double.toString(d))) == 0不起作用,因为即使number.doubleValue() 正好0.1Double.toString()仍会将其转换为{{1} }} String因为没有"0.1"值更接近“真实”double