首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java精度损失

Java精度损失
EN

Stack Overflow用户
提问于 2010-03-05 19:38:25
回答 3查看 2.2K关注 0票数 1

我担心失去精确性

我的任务是把数字打印成字符串。

代码语言:javascript
复制
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.399999999999999999998E-7

如何解决这个问题?

UPD:主要问题是字符串输出格式化。我不为损失大约0.00000001美元而烦恼。现在我把它解为String.format("%f",值),但我认为这不是一个好方法。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-03-05 21:41:14

正如其他人所提到的,您必须使用java.math.BigDecimal而不是float/double。然而,这也伴随着它自己的一系列问题。

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

代码语言:javascript
复制
BigDecimal oneTenth = new BigDecimal(0.1);
BigDecimal oneMillion = new BigDecimal(1000000);
oneTenth.multiply(oneMillion)
out> 100000.0000000000055511151231257827021181583404541015625000000

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

代码语言:javascript
复制
BigDecimal oneTenth = new BigDecimal("0.1");
BigDecimalr oneMillion = new BigDecimal(1000000);
oneTenth.multiply(oneMillion)
out> 100000.0

您可以阅读更多关于BigDecimal的限制的约书亚布洛赫和尼尔加弗的精彩的Java难题书和在信息文章。最后,请注意,BigDecimal上的toString将以科学表示法打印,因此您必须正确地使用toPlainString

票数 3
EN

Stack Overflow用户

发布于 2010-03-05 19:40:30

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

票数 2
EN

Stack Overflow用户

发布于 2010-03-05 19:39:36

在上面搜索“浮点数”,你会得到很多关于为什么会发生这种情况的答案。它与浮点数在计算机中的表示方式有关。

浮点是如何存储的?什么时候有关系?

关于这个问题的另一篇文章- 浮点逼近

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2389457

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档