Tom*_*m K 5 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);
Run Code Online (Sandbox Code Playgroud)
我想要做的是将字符串文字与双重转换进行比较,以查看字符串中的值是否可以用double精确表示.例如:
".5"== .5?预期答案:是的.
".1"== .1?预期答案:没有.
我正在尝试的比较是
number = new BigDecimal("0.1");
d = number.doubleValue();
if (number.compareTo(new BigDecimal(Double.toString(d))) == 0){
// Doing something
}
Run Code Online (Sandbox Code Playgroud)
任何帮助理解为什么这不区分可以和不能用double表示的值将是值得赞赏的.
要测试 a 是否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
}
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为new BigDecimal(s)产生的BigDecimal值完全等于 所表示的值String,而是最接近new BigDecimal(Double.parseDouble(s))该值的精确值。 double
我会在最后解释为什么number.compareTo(new BigDecimal(Double.toString(d))) == 0不起作用。
当你这样做时
double d = 0.1;
System.out.println(d);
Run Code Online (Sandbox Code Playgroud)
你得到答案是0.1因为d它最接近double“真实” 0.1。(double d = 0.1; 意思是“d最接近double” 0.1。当你写
System.out.println(d + d + d + d + d + d + d + d + d + d);
Run Code Online (Sandbox Code Playgroud)
你看0.9999999999999999而不是1。您看不到的原因1是因为存在double比答案更接近 1 的值(实际上 1double本身就是一个值)。没有理由为什么答案应该是最接近的double,因为d并不是真正的0.1答案(它只是接近它),并且在任何情况下,当您添加浮点数时都会引入不准确的情况。
最后,number.compareTo(new BigDecimal(Double.toString(d))) == 0不起作用,因为即使number.doubleValue()不完全,仍然将其转换为0.1,因为没有更接近“真实”的值。Double.toString()String "0.1"double0.1