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