繁体   English   中英

java.lang.Double的精度损失

[英]Precision loss with java.lang.Double

假设我有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.

如果将这些值加在一起,是否会失去精度?

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

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

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

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

不降低精度的解决方案是使用具有潜在增长精度的数字格式,例如BigDecimal-不限于固定位数。

我正在使用精度为三个十进制数字的十进制浮点算法,并且(大致)具有与典型二进制浮点算法相同的功能。 假设您有123.0和4.56。 这些数字由尾数(0 <= m <1)和指数表示:0.123 * 10 ^ 3和0.456 * 10 ^ 1,我将分别写为<.123e3>和<.456e1>。 除非指数相等,否则不可能立即将两个这样的数字相加,这就是为什么根据以下条件进行相加的原因:

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

您会看到根据通用指数对十进制数字进行必要的对齐会导致精度下降。 在极端情况下,整个加数可能会变成虚无。 (想对一个无穷级数求和,这些项变得越来越小,但仍会大大有助于计算得出的和。)

其他不精确性的原因是二进制和十进制小数之间的差异,在这种情况下,一个基数中的精确分数不能正确地用另一基数表示。

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

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

尝试这个

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

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM