简体   繁体   English

java.lang.Double的精度损失

[英]Precision loss with java.lang.Double

Say I have 2 double values. 假设我有2个double值。 One of them is very large and one of them is very small. 其中之一很大,其中之一很小。

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.

If I add those values together, do I lose precision? 如果将这些值加在一起,是否会失去精度?

In other words, does the max possible double value increase if I assign an int value to it? 换句话说,如果我给它分配一个int值,最大可能的double值会增加吗? And does the min possible double value decrease if I choose a small integer part? 如果我选择较小的整数部分,最小可能的double值会减小吗?

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

double values are not evenly distributed over all numbers. double值未均匀地分布在所有数字上。 double uses the floating point representation of the number which means you have a fixed amount of bits used for the exponent and a fixed amount of bits used to represent the actual "numbers"/mantissa. double使用数字的浮点表示形式,这意味着您有固定数量的用于指数的位数和固定数量的用于代表实际“数字” /尾数的位数。

So in your example using a large and a small value would result in dropping the smaller value since it can not be expressed using the larger exponent. 因此,在您的示例中,使用较大和较小的值将导致丢弃较小的值,因为无法使用较大的指数表示该值。

The solution to not dropping precision is using a number format that has a potentially growing precision like BigDecimal - which is not limited to a fixed number of bits. 不降低精度的解决方案是使用具有潜在增长精度的数字格式,例如BigDecimal-不限于固定位数。

I'm using a decimal floating point arithmetic with a precision of three decimal digits and (roughly) with the same features as the typical binary floating point arithmetic. 我正在使用精度为三个十进制数字的十进制浮点算法,并且(大致)具有与典型二进制浮点算法相同的功能。 Say you have 123.0 and 4.56. 假设您有123.0和4.56。 These numbers are represented by a mantissa (0<=m<1) and an exponent: 0.123*10^3 and 0.456*10^1, which I'll write as <.123e3> and <.456e1>. 这些数字由尾数(0 <= m <1)和指数表示:0.123 * 10 ^ 3和0.456 * 10 ^ 1,我将分别写为<.123e3>和<.456e1>。 Adding two such numbers isn't immediately possible unless the exponents are equal, and that's why the addition proceeds according to: 除非指数相等,否则不可能立即将两个这样的数字相加,这就是为什么根据以下条件进行相加的原因:

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

You see that the necessary alignment of the decimal digits according to a common exponent produces a loss of precision. 您会看到根据通用指数对十进制数字进行必要的对齐会导致精度下降。 In the extreme case, the entire addend could be shifted into nothingness. 在极端情况下,整个加数可能会变成虚无。 (Think of summing an infinite series where the terms get smaller and smaller but would still contribute considerably to the sum being computed.) (想对一个无穷级数求和,这些项变得越来越小,但仍会大大有助于计算得出的和。)

Other sources of imprecision result from differences between binary and decimal fractions, where an exact fraction in one base cannot be represented without error using the other one. 其他不精确性的原因是二进制和十进制小数之间的差异,在这种情况下,一个基数中的精确分数不能正确地用另一基数表示。

So, in short, addition and subtraction between numbers from rather different orders of magnitude are bound to cause a loss of precision. 因此,简而言之,不同数量级的数字之间的加减法必然会导致精度损失。

If you try to assign too big value or too small value a double, compiler will give an error: 如果您尝试分配太大或太小的值,则编译器将给出错误消息:

try this 尝试这个

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

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

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