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 使用数字的浮点表示,这意味着您有固定数量的位用于指数和固定数量的位用于表示实际 "numbers"/尾数。
因此,在您的示例中,使用较大值和较小值会导致丢弃较小的值,因为它无法使用较大的指数表示。
不降低精度的解决方案是使用具有潜在增长精度的数字格式,如 BigDecimal - 它不限于固定位数。
如果您尝试为 double 分配太大或太小的值,编译器将给出错误:
试试这个
double d1 = 1e-1000;
double d2 = 1e+1000;
我使用的是十进制浮点运算,精度为三位十进制数字,并且(大致)具有与典型二进制浮点运算相同的功能。假设您有 123.0 和 4.56。这些数字由尾数 (0<=m<1) 和指数表示:0.123*10^3 和 0.456*10^1,我将其写为 <.123e3> 和 <.456e1>。除非指数相等,否则不可能立即将两个这样的数字相加,这就是加法根据以下公式进行的原因:
<.123e3> <.123e3>
<.456e1> <.004e3>
--------
<.127e3>
您看到根据公共指数对小数位进行必要的对齐会导致精度损失。在极端情况下,整个加数可能会变成虚无。 (考虑对一个无限级数求和,其中的项变得越来越小,但仍会对计算的总和做出很大贡献。)
不精确的其他来源是二进制和十进制小数之间的差异,其中一个基数中的精确分数无法使用另一个基数准确无误地表示。
所以,简而言之,不同数量级的数字之间的加减法必然会导致精度损失。
假设我有 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 使用数字的浮点表示,这意味着您有固定数量的位用于指数和固定数量的位用于表示实际 "numbers"/尾数。
因此,在您的示例中,使用较大值和较小值会导致丢弃较小的值,因为它无法使用较大的指数表示。
不降低精度的解决方案是使用具有潜在增长精度的数字格式,如 BigDecimal - 它不限于固定位数。
如果您尝试为 double 分配太大或太小的值,编译器将给出错误:
试试这个
double d1 = 1e-1000;
double d2 = 1e+1000;
我使用的是十进制浮点运算,精度为三位十进制数字,并且(大致)具有与典型二进制浮点运算相同的功能。假设您有 123.0 和 4.56。这些数字由尾数 (0<=m<1) 和指数表示:0.123*10^3 和 0.456*10^1,我将其写为 <.123e3> 和 <.456e1>。除非指数相等,否则不可能立即将两个这样的数字相加,这就是加法根据以下公式进行的原因:
<.123e3> <.123e3>
<.456e1> <.004e3>
--------
<.127e3>
您看到根据公共指数对小数位进行必要的对齐会导致精度损失。在极端情况下,整个加数可能会变成虚无。 (考虑对一个无限级数求和,其中的项变得越来越小,但仍会对计算的总和做出很大贡献。)
不精确的其他来源是二进制和十进制小数之间的差异,其中一个基数中的精确分数无法使用另一个基数准确无误地表示。
所以,简而言之,不同数量级的数字之间的加减法必然会导致精度损失。