Java的精度损失与大双精度

Java的精度损失与大双精度,java,double,Java,Double,打印1.0715086071862673E301 我尝试过的事情 我尝试使用BigDecimal类扩展此数字: double lnumber = Math.pow(2, 1000); 这只是打印: 10715086071862673000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

打印
1.0715086071862673E301

我尝试过的事情

我尝试使用BigDecimal类扩展此数字:

 double lnumber = Math.pow(2, 1000);
这只是打印:

10715086071862673000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

我还尝试使用DecimalFormat:

 String strNumber = new BigDecimal(Double.toString(lnumber)).toPlainString();
打印相同的内容:

10715086071862673000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

根据Wolfram Alpha,实际答案是


如何打印所有实际值?

您不能像这样混合匹配数学、基本类型和BigDecimal,如果您想要真正的精度,只需使用BigDecimal:

    DecimalFormat df = new DecimalFormat("#");
    df.setMaximumFractionDigits(0);
    String strNumber = String.valueOf(df.format(lnumber));

您不能像那样混合和匹配数学、基本类型和BigDecimal,如果您想要真正的精度,只需使用BigDecimal:

    DecimalFormat df = new DecimalFormat("#");
    df.setMaximumFractionDigits(0);
    String strNumber = String.valueOf(df.format(lnumber));

如果要查看double的实际值,请使用BigDecimal(double)构造函数<代码>双精度。toString(lnumber)进行舍入

System.out.println(新的BigDecimal((Math.pow(21000)))
输出10715086071862673209484250490906000181051404811705533360744375038837035105112493612249319837885858127594672917553146825871452856921043598457746985748574848393456748242309854210746062711418754182153649835819412673987676751655946077629119647765421766042316526286720566806976


pow(21000)完全可以用double表示,因为它是可表示范围内的二的幂。

如果您想查看double的实际值,请使用BigDecimal(double)构造函数<代码>双精度。toString(lnumber)进行舍入

System.out.println(新的BigDecimal((Math.pow(21000)))
输出10715086071862673209484250490906000181051404811705533360744375038837035105112493612249319837885858127594672917553146825871452856921043598457746985748574848393456748242309854210746062711418754182153649835819412673987676751655946077629119647765421766042316526286720566806976


Math.pow(21000)完全可以用double表示,因为它是2的幂,在可表示的范围内。

你知道
double
只有大约16位精度,对吗?我建议阅读。
0.0
是精确的。但是,对于精度超过16位的值,有些是精确的,但大多数不是。在现实世界中,16是你无法衡量的。你能给出一个真实世界的例子,说明什么时候你需要计算到你所说的精度吗?双重结果与Wolfram Alpha结果匹配。唯一的问题是Double.toString调用,该调用将结果四舍五入。您确实知道
Double
只有大约16位精度,对吗?我建议阅读。
0.0
是精确的。但是,对于精度超过16位的值,有些是精确的,但大多数不是。在现实世界中,16是你无法衡量的。你能给出一个真实世界的例子,说明什么时候你需要计算到你所说的精度吗?双重结果与Wolfram Alpha结果匹配。唯一的问题是对结果进行四舍五入的Double.toString调用。作为一个推论,它也作为的兄弟存在。它们将比原语慢,但这是更高精度的代价。为什么不能混合和匹配数学和原语类型,只要操作正确?我经常使用BigDecimal来获取浮点或双精度的精确值。@PatriciaShanahan,因为您不能正确地执行它。如果在浮点数之间执行单个操作,可能已经失去精度,而BigDecimal无法修复它(尝试创建一个
BigDecimal
,结果为
1.01+1.17
,结果肯定不是您所期望的)@MaurícioLinhares最接近1.01的双精度的精确值为1.0100000000088817841970012523233890533447265625。最接近1.17的double的精确值为1.16999999929289457264239899814128875732421875。他们的总数是2.179999999999378275106209912337362766265869140625。它们之和的双重近似值为2.1799999999971578290569595992565155029296875,这正好显示了基于我对IEEE 754的理解,我预期的舍入误差。这说明了通过组合BigDecimal和double可以获得的信息。@PatriciaShanahan OP想要精确的精度,我刚才说的是精确的精度。如果你接受舍入误差,它就不再是精确的精度了,你也不需要用BigDecimal了。作为一个推论,它也作为一个兄弟存在。它们将比原语慢,但这是更高精度的代价。为什么不能混合和匹配数学和原语类型,只要操作正确?我经常使用BigDecimal来获取浮点或双精度的精确值。@PatriciaShanahan,因为您不能正确地执行它。如果在浮点数之间执行单个操作,可能已经失去精度,而BigDecimal无法修复它(尝试创建一个
BigDecimal
,结果为
1.01+1.17
,结果肯定不是您所期望的)@MaurícioLinhares最接近1.01的双精度的精确值为1.0100000000088817841970012523233890533447265625。最接近1.17的double的精确值为1.16999999929289457264239899814128875732421875。他们的总数是2.179999999999378275106209912337362766265869140625。它们之和的双重近似值为2.1799999