Java 精度损失

发布于 2024-08-24 05:20:34 字数 534 浏览 4 评论 0原文

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

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

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), 但我认为这不是好方法

I have a problem concerned with losing of precision

my task is to print numbers as strings

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);

for example, 0.2*7=1.4000000000000001; 0.0000014/10=1.3999999999999998E-7

how to figure out this problem?

UPD: The main problem is string output formating. i don't bother about losting of about 0.00000001 value.
Now I solved it as String.format("%f", value),
but I think it's not good approach

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夜血缘 2024-08-31 05:20:34

正如其他人提到的,您必须使用 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 中阅读有关 BigDecimal 限制的更多信息以及 Neal Gafter 精彩的 Java puzzlers 书籍和 这篇内容丰富的文章。最后请注意,BigDecimal 上的 toString 将以科学计数法打印,因此您必须正确使用 toPlainString 来代替。

As mentioned by others you have to use java.math.BigDecimal instead of float/double. This however comes with its own set of problems.

For instance when you call BigDecimal(double) the value you pass in will be expanded to its full representation:

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

But when you use the BigDecimal(String) constructor the eact value is represented and you get

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

You can read more on BigDecimal's limitations in Joshua Bloch and Neal Gafter's splendid Java puzzlers book and in this informative article. Finally note that toString on BigDecimal's will print in scientific notation so you will properly have to use toPlainString instead.

凉薄对峙 2024-08-31 05:20:34

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

The double type does not have infinite precision and cannot represent decimals exactly. You are observing normal rounding errors. For arbitrary precision arithmetic, you will need to use java.math.BigDecimal instead.

梦开始←不甜 2024-08-31 05:20:34

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

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

关于此事的另一篇文章 - 浮点近似值

Search for "floating point numbers" on SO and you'll get a slew of answers as to why this happens. It has to do with how floating point numbers are represented in computers.

How is floating point stored? When does it matter?

Another article on the matter - Floating Point Approximation

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文