简体   繁体   English

一般浮点数学查询

[英]General floating-point maths query

Okay so I get that some numbers can't be represented properly in binary just like 1/3 can't be fully represented in decimal. 好的,所以我得到一些数字不能用二进制正确表示,就像1/3不能用十进制完全表示一样。

So how come when I console.log(0.3) it returns 0.3 but when I console.log(0.1 + 0.2) it returns the 0.30000000000000004 那么为什么我在console.log(0.3)它返回0.3但是当我在console.log(0.1 + 0.2)时返回0.30000000000000004

How come it is accounting for the error (if it even is) when simply outputting 0.3 but doesn't when the addition occurs? 为什么简单地输出0.3时会出现错误(如果是偶数),但是当加法发生时却没有?

Suppose we approximate 1/3 and 2/3 in decimal. 假设我们以十进制表示约1/3和2/3。

1/3 = 0.333
2/3 = 0.667

and we add 1/3+1/3: 我们加1/3 + 1/3:

1/3+1/3 = 0.333 + 0.333 = 0.666

We didn't get our approximation of 2/3. 我们没有得到2/3的近似值。 Rounding 1/3 to something we can represent in decimal didn't produce a number equal to half of what we got when we rounded 2/3. 将1/3舍入到我们可以用十进制表示的东西时,产生的数字不会等于我们舍入2/3时得到的数字的一半。

The same thing happens in binary. 同样的事情发生在二进制中。 We round 0.1 and 0.2 to numbers we can represent in binary, but the sum of the approximations is slightly different from what we get if we approximate 0.3. 我们将0.1和0.2舍入到我们可以用二进制表示的数字,但是近似值的总和与我们得到的数值略有不同(如果我们接近0.3)。 We get something a bit higher, and the result is displayed as 0.30000000000000004 . 我们得到一些更高的东西,结果显示为0.30000000000000004

The inaccuracies in the internal representations of 0.1 and 0.2 are small enough that the Javascript printer ignores them when it's printing these numbers. 0.10.2的内部表示中的不准确性足够小,以至于Javascript打印机在打印这些数字时会忽略它们。 But when you add them together the inaccuracies accumulate, and this is enough to show up when the result is printed. 但是当你将它们加在一起时会产生不准确性,这足以在打印结果时显示出来。

The way Java prints floating-point numbers is a significant part of the behavior you are seeing: By default, Java does not print the exact value of a floating-point number. Java打印浮点数的方式是您所看到的行为的重要部分:默认情况下,Java不会打印浮点数的确切值。 It prints just enough digits to precisely identify the double that is being printed. 它打印的数字足以精确识别正在打印的double精度数。

Thus, if you set x to .3 , x is actually set to 0.299999999999999988897769753748434595763683319091796875. 因此,如果将x设置为.3 ,则x实际设置为0.299999999999999988897769753748434595763683319091796875。 When Java prints this, it prints only “.3”, because converting “.3” to double yields the value of x , 0.299999999999999988897769753748434595763683319091796875. 当Java打印出来时,它只打印“.3”,因为将“.3”转换为double产生x的值,即0.299999999999999988897769753748434595763683319091796875。

When you use .1 and .2 , these are actually the values 0.1000000000000000055511151231257827021181583404541015625 and 0.200000000000000011102230246251565404236316680908203125. 使用.1.2 ,这些实际上是值0.1000000000000000055511151231257827021181583404541015625和0.200000000000000011102230246251565404236316680908203125。 When you add them (in double format), the result is 0.3000000000000000444089209850062616169452667236328125. 添加它们( double格式)时,结果为0.3000000000000000444089209850062616169452667236328125。

When you print this value, Java prints “0.30000000000000004” because it needs to show all those digits in order to produce a numeral that, when converted back to double , will produce 0.3000000000000000444089209850062616169452667236328125. 当您打印此值时,Java会打印“0.30000000000000004”,因为它需要显示所有这些数字,以便生成一个数字,当转换回double ,将产生0.3000000000000000444089209850062616169452667236328125。


Here is the documentation for how double values are printed . 以下是有关如何打印double值的文档 It says: 它说:

How many digits must be printed for the fractional part…? 小数部分必须打印多少位数? There must be at least one digit to represent the fractional part, and beyond that as many, but only as many, more digits as are needed to uniquely distinguish the argument value from adjacent values of type double . 必须至少有一个数字来表示小数部分,并且除此之外必须有多个,但只有多少,更多的数字才能唯一地将参数值与double类型的相邻值区分开来。

As you said, in base 10 you can't accurately describe the fraction 1/3. 正如你所说,在基数10中你无法准确描述1/3的分数。 Similarly, in base 2, you can't accurately describe certain other fractions. 同样,在基数2中,您无法准确描述某些其他分数。 So, when the computer adds 0.1 and 0.2, it's actually adding something like 0.10000000001 and 0.20000000003. 因此,当计算机增加0.1和0.2时,它实际上增加了0.10000000001和0.20000000003。

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

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