为什么 Visual Studio 2008 告诉我 .9 - .8999999999999995 = 0.00000000000000055511151231257827?

发布于 2024-08-09 22:12:54 字数 228 浏览 11 评论 0 原文

当我在 Visual Studio 2008 立即窗口中输入以下内容时:

? .9 - .8999999999999995

它给了我这个答案:

0.00000000000000055511151231257827

该文档说 double 有 15-16 位精度,但它给了我一个 32 位精度的结果。这些额外的精度从何而来?

When I type this into the Visual Studio 2008 immediate window:

? .9 - .8999999999999995

It gives me this as the answer:

0.00000000000000055511151231257827

The documentation says that a double has 15-16 digits of precision, but it's giving me a result with 32 digits of precision. Where is all that extra precision coming from?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

狼亦尘 2024-08-16 22:12:54

答案只有 15-16 位数字。所有这些前导零都不算数。这个数字实际上更像是 5.5511151231257827 × 10-16。尾数部分有 15-16 位数字。指数 (-16) 用于将小数点移动 16 位,但不会改变总数的位数。

编辑

收到一些评论后,我现在很好奇到底发生了什么。我将有问题的数字插入此 IEEE-754 转换器。它冒昧地将最后一个“27”四舍五入为“30”,但我认为这不会改变结果。

转换器将数字分解为三个二进制部分:

符号:0(正)
指数:-51
有效位数:1.0100000000000000000000000000000000000000000000000000(二进制为 1.2510

,因此该数字为 1.012 × 2-51 或 1.2510 > × 2-51。由于只存储了三个有效的二进制数字,这表明拉尔斯可能有所发现。它们不能是“随机噪声”,因为每次转换数字时它们都是相同的。

数据表明唯一存储的数字是“5”。前导零来自指数,其余看似随机的数字来自计算 2-51

There are only 15-16 digits in the answer. All those leading zeroes don't count. The number is actually more like 5.5511151231257827 × 10-16. The mantissa portion has 15-16 digits in it. The exponent (-16) serves to shift the decimal point over by 16 places, but doesn't change the number of digits in the overall number.

Edit

After getting some comments, I'm curious now about what's really going on. I plugged the number in question into this IEEE-754 Converter. It took the liberty of rounding the last "27" into "30", but I don't think that changes the results.

The converter breaks down the number into its three binary parts:

Sign: 0 (positive)
Exponent: -51
Significand: 1.0100000000000000000000000000000000000000000000000000 (binary for 1.2510)

So this number is 1.012 × 2-51, or 1.2510 × 2-51. Since there are only three significant binary digits being stored, that would suggest that Lars may be onto something. They can't be "random noise" since they are the same each time the number is converted.

The data suggests that the only stored digit is "5". The leading zeros come from the exponent and the rest of the seemingly-random digits are from computing 2-51.

揪着可爱 2024-08-16 22:12:54

您应该阅读:每个计算机科学家应该做什么
了解浮点运算

基本上,它归结为以有限精度存储的浮点数。你必须与一些三角洲进行比较。

if(.9 - .8999999999999995 <= 0.0001)
  //close enough to be equal

You should read: What Every Computer Scientist Should
Know About Floating-Point Arithmetic
.

Basically it comes down to Floating Point numbers being stored with finite precision. You have to do your comparison with some delta.

if(.9 - .8999999999999995 <= 0.0001)
  //close enough to be equal
ゃ懵逼小萝莉 2024-08-16 22:12:54

前导零并不重要/精度的一部分(就浮点数而言 - 从数学上来说,它们很重要)。前导零是由于浮点数内部表示的指数部分造成的。

55511151231257827 部分(即有效数字尾数)有 17 位十进制数字,足够接近 15-16 位数字。

@Lars D:您认为正确的内容仅在问题的上下文中才是正确的。 .9 - .8999999999999995 计算出有效数为 0.625、指数为 -50 的浮点数。取 0.625 * 2-50 结果为 5.5511151231257827e-16。现在,脱离原始问题的上下文,我们得到了一个具有 17 位有效数字的数字,它恰好是 0.0000000000000005 的最佳二进制近似值。然而,就浮点数的表示而言,那些前导零仍然不重要。

The leading zeros are not significant/part of the precision (as far as the floating point number is concerned -- mathematically speaking, they are significant). The leading zeros are due to the exponent part of the floating point number's internal representation.

The portion 55511151231257827 (which is the significand or mantissa) has 17 decimal digits, which is close enough to 15-16 digits.

@Lars D: What you consider to be correct, is only correct within the context of the question. .9 - .8999999999999995 works out to a float with significand 0.625 and exponent of -50. Taking 0.625 * 2-50 results in 5.5511151231257827e-16. Now, out of the context of the original question, we have a number with 17 significant digits which does happen to be our best binary approximation of 0.0000000000000005. However, those leading zeros are still not significant as far as the representation of the floating point number is concerned.

破晓 2024-08-16 22:12:54

? .9 - .8999999999999995

这个具有 15-16 个有效数字的减法过程给出

0.0000000000000005

其余数字只是舍入误差。但是,由于计算机始终在第一个非零数字之后存储 15-16 个有效数字,因此会显示舍入误差,并且您会得到许多由舍入误差产生的尾随随机数字。因此,减法运算的结果有 16 位有效数字加上结果存储中的 16 位数字,即 32 位数字。

? .9 - .8999999999999995

This subtraction process, with 15-16 significant digits, gives

0.0000000000000005

The rest of the digits are just rounding errors. However, since the computer always stores 15-16 significant digits after the first non-zero digit, the rounding errors are shown, and you get a lot of trailing random digits produced by rounding errors. So the result has 16 significant digits from the subtraction operation plus 16 digits from the storage of the result, which gives 32 digits.

南冥有猫 2024-08-16 22:12:54

“浮点”的“浮动”部分意味着您得到的值更接近 5.5511151231257827 * 10^(-16)。这并不完全是它的表示方式,因为当然它都是在底层以二进制形式完成的,但重点是,该数字由有效数字表示,加上一个表示移动基数(小数点)多远的数字。与往常一样,维基百科可以为您提供更多详细信息:

(第二个链接更具体地关注您的具体情况。)

The "floating" part of "floating point" means that you are getting something closer to 5.5511151231257827 * 10^(-16). That's not exactly how it's represented, because of course it's all done in binary under the hood, but the point is, the number is represented by the significant digits, plus a number which represents how far to move the radix (decimal point). As always, wikipedia can give you more detail:

(The second link is more specifically focused on your particular case.)

无所的.畏惧 2024-08-16 22:12:54

我认为这是因为在二进制系统中,5 是周期性的,因为它不能被 2 整除。然后 Mark Rushakoff 所说的适用。

I think its because in the binary system, 5 is periodic as it is not dividable by 2. And then what Mark Rushakoff said applies.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文