我正在尝试确定double的最大精度是多少。在此链接中接受的答案的评论中Retain precision with double in Java @PeterLawrey表示最高精度为15。
你如何确定这个?
答案 0 :(得分:9)
@PeterLawrey表示最高精度为15。
实际上并不是他所说的。他说的是:
double有15位小数的精度
他错了。它们具有15个十进制数字的准确度。
任何数字中的小数位数由其日志给予基数10. 15是log 10 (2 53 -1)的最低值,其中53是尾数的位数(包括隐含位),如Javadoc和IEEE 754中所述,2 53 -1因此是最大可能的尾数值。实际值是15.954589770191003298111788092734到Windows计算器的限制。
将其描述为小数位数的准确性是错误的。 double
有15个十进制数的精度,如果它们都在小数点之前。对于带小数部分的数字,你可以获得超过15位的数字。十进制表示,因为十进制和二进制分数的不可通约性。
答案 1 :(得分:0)
你也可以直接“测量”它:
for(double d = 1 ; d > 0 ; d/=2) System.out.println(d);
这段代码的想法是用一位来达到最小的数字。所以你从1
(只有1位)开始并除以2(它以二进制向右移位)直到你到达最后一位。此循环打印的最后一个数字是:
4.9E-324
答案 2 :(得分:0)
运行此代码,查看停止位置
public class FindPrecisionDouble {
static public void main(String[] args) {
double x = 1.0;
double y = 0.5;
double epsilon = 0;
int nb_iter = 0;
while ((nb_iter < 1000) && (x != y)) {
System.out.println(x-y);
epsilon = Math.abs(x-y);
y = ( x + y ) * 0.5;
}
final double prec_decimal = - Math.log(epsilon) / Math.log(10.0);
final double prec_binary = - Math.log(epsilon) / Math.log(2.0);
System.out.print("On this machine, for the 'double' type, ");
System.out.print("epsilon = " );
System.out.println( epsilon );
System.out.print("The decimal precision is " );
System.out.print( prec_decimal );
System.out.println(" digits" );
System.out.print("The binary precision is " );
System.out.print( prec_binary );
System.out.println(" bits" );
}
}
变量y
成为与1.0
不同的最小值。在我的计算机(Mac Intel Core i5)上,它停在1.1102...E-16
。然后打印精度(十进制和二进制)。
如https://en.wikipedia.org/wiki/Machine_epsilon中所述,可以使用epsilon值估计浮点精度。 它是“当加到一个时产生不同于一个的结果的最小数字”(我做了一个小变化:1-e而不是1 + e,但逻辑是相同的)
我将用十进制解释:如果你有一个4位小数的精度,你可以表示1.0000 - 0.0001,但你不能表示数字1.00000-0.00001(你缺少小数点后5位)。在此示例中,精度为4位小数,epsilon为0.0001。 epsilon直接测量浮点精度。只需转置为二进制。
修改您的问题是“如何确定......”。您正在搜索的答案更多的是解释而不是确定精度的方法(您接受的答案)。无论如何,对于其他人来说,在机器上运行此代码将决定“双”类型的精度。
答案 3 :(得分:-2)
double
的最大精度是第一个大于0的值。根据Double的Javadoc,这个数字由Double.MIN_VALUE
表示。您可以按如下方式输出:
BigDecimal doubleMinVal = BigDecimal.valueOf(Double.MIN_VALUE);
System.out.println(doubleMinVal.toPlainString());
System.out.println(doubleMinVal.toString());
有关示例,请参阅this IDEOne program。