使用java.lang.Double精确丢失

时间:2015-01-08 12:14:17

标签: java double precision double-precision

说我有2 double个值。其中一个非常大,其中一个非常小。

double x = 99....9;  // I don't know the possible max and min values,
double y = 0,00..1;  // so just assume these values are near max and min.

如果我将这些值加在一起,我会失去精确度吗?

换句话说,如果我为其分配double值,最大可能int值会增加吗?如果我选择一个小整数部分,最小可能的double值是否会减少?

double z = x + y;    // Real result is something like 999999999999999.00000000000001

3 个答案:

答案 0 :(得分:4)

双值不均匀分布在所有数字上。 double使用数字的浮点表示,这意味着您具有用于指数的固定位数和用于表示实际“数字”/尾数的固定位数。

因此,在您的示例中,使用大值和小值会导致丢弃较小的值,因为无法使用较大的指数表示。

不丢弃精度的解决方案是使用具有可能增长的精度的数字格式,如BigDecimal - 不限于固定的位数。

答案 1 :(得分:1)

我正在使用十进制浮点运算,精度为三位十进制数,并且(大致)具有与典型二进制浮点运算相同的特性。假设你有123.0和4.56。这些数字由尾数(0 <= m <1)和指数:0.123 * 10 ^ 3和0.456 * 10 ^ 1表示,我将其写为&lt; .123e3&gt;。和&lt; .456e1&gt;。除非指数相等,否则不可能立即添加两个这样的数字,这就是为什么按照以下内容进行添加:

 <.123e3>   <.123e3>
 <.456e1>   <.004e3>
            --------
            <.127e3>

您会发现根据公共指数对十进制数字进行必要的对齐会导致精度损失。在极端情况下,整个加数可能会转变为虚无。 (想想总结一个无限系列,其中术语变得越来越小但仍然会对计算的总和做出相当大的贡献。)

其他不精确的来源是二进制和小数分数之间的差异,其中一个基数中的精确分数无法使用另一个基数无错误地表示。

因此,简而言之,从相当不同的数量级的数字之间的加法和减法必然会导致精度的损失。

答案 2 :(得分:0)

如果您尝试分配太大的值或太小的值double,编译器将给出错误:

试试这个

    double d1 =  1e-1000;
    double d2 =  1e+1000;