簡體   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