繁体   English   中英

Java精度损失

[英]Java loss of precision

我有一个关于精度损失的问题

我的任务是将数字打印为字符串

int exponent = ...
int[] Mantissas = { 1, 2, 5 };
double dataStep = java.lang.Math.pow(10.0, exponent) * Mantissas[mantissaIndex];
...
for (int i = 0; i < NSteps; i++)
                    steps[i] = firstStep + i * dataStep;
draw(steps);

例如0.2 * 7 = 1.4000000000000001; 0.0000014 / 10 = 1.3999999999999998E-7

如何解决这个问题?

UPD :主要问题是字符串输出格式。 我不担心丢失约0.00000001的值。 现在,我将其解析为String.format(“%f”,value),但我认为这不是一个好方法

正如其他人所提到的,您必须使用java.math.BigDecimal而不是float / double。 但是,这有其自身的一系列问题。

例如,当您调用BigDecimal(double)时,您传入的值将扩展为其完整表示形式:

BigDecimal oneTenth = new BigDecimal(0.1);
BigDecimal oneMillion = new BigDecimal(1000000);
oneTenth.multiply(oneMillion)
out> 100000.0000000000055511151231257827021181583404541015625000000

但是,当您使用BigDecimal(String)构造函数时,会表示eact值,并且您得到

BigDecimal oneTenth = new BigDecimal("0.1");
BigDecimalr oneMillion = new BigDecimal(1000000);
oneTenth.multiply(oneMillion)
out> 100000.0

您可以在Joshua Bloch和Neal Gafter的出色的Java益智类书籍以及这篇内容丰富的文章中了解有关BigDecimal限制的更多信息。 最后请注意,BigDecimal上的toString将以科学计数法打印,因此您必须正确地使用toPlainString

double类型没有无限的精度,不能精确地表示小数。 您正在观察正常的舍入错误。 对于任意精度算术,您将需要使用java.math.BigDecimal代替。

在SO上搜索“浮点数”,您将获得大量答案,了解发生这种情况的原因。 它与计算机中浮点数的表示方式有关。

浮点如何存储? 什么时候重要?

关于此问题的另一篇文章- 浮点近似

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM