我在一个单元格中=2*10^15
评估为2,000,000,000,000,000
,而另一个单元格中=2+2*10^15
也评估为2,000,000,000,000,000
,这很好,因为精度只是15位数。但是当我然后从另一个中减去一个时,我会回到2
,我不知道它来自哪里。据我所知2*10^15
有一个确切的二进制表示,所以我想在向它添加2
时,它只是“被删除”。但似乎我的理解是不正确的。
实际上,据我所知,2E+15
的二进制表示在1
的权力等于2
的地方有{50,49,48,44,43,41,39,38,37,36,35,34,32,30,27,24,23,19,18,16}
,为什么可以'我们只是添加了另一个与power 1
对应的位,并准确表示2+2E+15
?
此外,如果我2
代替1
而不是2*10^15
,那么Excel电子表格中1+2*10^15
和0
之间的差异为2 + 2E+15
,但如果我这样做在Excel VBA中进行相同的计算,然后我回来1.那是什么?
我已经阅读过(好几次)“每个计算机科学家应该知道的关于浮点算术的内容”,但是那里的讨论似乎集中在小数而不是整数上,或者我只是没有得到它。
添加1
我记得刚才我在VBA写了一个函数来获取Excel存储的数字的二进制表示(这个函数可以在这里找到)
Extract mantissa, exponent and sign data from IEEE-754 double in VBA)。因此,如果我将该函数应用于1
,它会在尾数的第4个位置返回一个带有2E+15
的二进制文件(不知道为什么是第4个),当函数应用于{{ 1}},所以看起来Excel似乎只是选择以15位精度显示数字,即使底层存储的浮点数具有更大的精度。
添加2
事实证明,2 + 2E+15
的尾数中的额外位在第4位(而不是第2位)的原因是尾数通过丢弃前(最左)位而被“标准化”(因为它始终是1)并通过移动所有剩余的东西将尾数的长度调整为52位,最后将2 0添加到“简单”二进制表示,以便
1110-0011-0101-1111-1010-1001-0011-0001-1010-0000-0000-0000-010
变
1100-0110-1011-1111-0101-0010-0110-0011-0100-0000-0000-0000-1000
。
似乎由于尾数的这种归一化,浮点双重表示的精度实际上是18位小数,例如,数字1.75 + 2E+15
可以用尾数1100-0110-1011-1111-0101-0010-0110-0011-0100-0000-0000-0000-0111
精确表示
只需要弄清楚指数发生了什么......有一种叫做“偏见”的东西......
答案 0 :(得分:1)
所以,我做了一些研究,因为我对这个问题很感兴趣。虽然我不能完全保证你这个答案绝对正确,但我们最接近正确的答案是最接近的(除非有专家介绍)。
我会尝试剖析这个问题:
我在一个单元格中有= 2 * 10 ^ 15,其评估为2,000,000,000,000,000 并且我在另一个单元格中有= 2 + 2 * 10 ^ 15,它也评估为 2,000,000,000,000,000,这是好的,因为精度只有15 数字。但是当我从另一个中减去一个时,我会回到2,这个 我不明白它来自哪里。 据我所知2 * 10 ^ 15has 一个确切的二进制表示,所以我会想到的时候 添加2,它只是“被丢弃”。但似乎是我的 理解是不正确的。
我认为在继续任何事情之前,我认为重要的是要说明, Excel (或其他一般的MS产品)在浮点精度方面是众所周知的。 / strong>即可。这里必须考虑一些不准确之处。
此外,这实际上是其中一个显示有误导性的事情。 屏幕上显示的数字实际上与您计算的数字不同。我的意思是,在您的情况下,2E + 15和2E + 15尽管显示相同不一定是相同的数字! (听起来很奇怪..)它们只是显示为相同的数字,因为浮动的第二个位置太小,excel认为它显示无关紧要
此外,如果不是2我加1,那么之间的区别 Excel电子表格中2 * 10 ^ 15和1 + 2 * 10 ^ 15为0,但如果我这样做的话 在Excel VBA中计算,然后我回来1.那是什么?
这是最难回答的部分。虽然我不能肯定地说这个,但我的猜测是,这是因为数字1上浮点运算结束时的1向下舍入为零,而2保持不变。一般来说,这似乎是那些奇怪的Excel浮动内容之一,如果没有专业知识就很难解释,而且只是发生了。
我已经阅读过(好几次)“每个计算机科学家应该知道什么 关于浮点算术“但似乎有讨论 专注于小数而不是整数或者我只是没有得到它。
您已经在处理小数(准确地说是双倍)。 Excel中的“数字”格式会根据您的需要自动将您的号码转换为数据类型。 但绝对不是使用整数
整数的定义范围为-2,147,483,648到2,147,483,647。这意味着,我们的数字远远超过了最大整数范围。 如果我们要将两个数字转换为整数,则两者都将被覆盖为数字2,147,483,647,结果为0差异我可以重现的最近代表是使用=FLOOR.MATH()
公式,降到最接近的倍数。
最后但同样重要的是,了解如何计算excel中的数学函数非常重要。如果你有一个公式,例如。 2+2*10^-15+2
计算的结果为4
。为什么?运算符优先级:*
优先于+
,^
优先于*
所以^表示,如果我们计算2+2*10^15 - 2*10^15
首先连接在一起作为数学公式并计算。这将导致x.......2 - x........0
,虽然在我们的Excel展示中它会显示为2E+15 - 2E+15
我创建了下表以供说明:
另请注意,使用 =FLOOR.MATH()
公式,我们将双打转换为最接近的倍数[不是整数!](如果我们使用=INT()
我们只会超出整数范围时收到#VALUE错误。 =FLOOR.MATH(N1) - FLOOR.MATH(N2)
之间的差异为0,但 N2 - N1
不是,因为我们使用不同的数字和精度进行计数。虽然这样并不完全相当于使用整数(因为它们不是......显然),它们是我能想到如果我们用它们计算会发生什么的最接近的表示。
但令我感到困惑的是,N2的=FLOOR.MATH()
函数似乎以.00
小数返回,而N1则没有。虽然两者都应该是完全相同的数字(最接近的倍数)。不确定这是否只是格式化故障或任何重要性。
总而言之,我知道这个答案提出了更多问题而不是答案,但希望对于其他人来说这将是一个很好的解决方案来回答这个问题并至少回答你的一些问题,如果不是他们都是。
答案 1 :(得分:0)
Excel将数字存储为双精度,总共使用64位。一位是符号,11位是从-1024到1024的指数(在基数2中),其余52位是分数。
使用这种方法,一个数字可以转换为双精度并且再次返回并且保证不变的最多有效数字是15.对于16和17个有效数字,这仅适用于某些数字。我假设这就是为什么excel只会在工作表中显示15位有效数字的原因。请注意,根据规范,Excel将存储值作为公式的结果,其精度高于DISPLAYS; [https://support.office.com/en-us/article/excel-specifications-and-limits-1672b34d-7043-467e-8e27-269d656771c3]
现在理论上我们应该能够准确地将整数表示为2 ^ 53 = 9,007,199,254,740,992。但是,Excel似乎只存储整数,最多为2 ^ 50 = 1,125,899,906,842,624。尝试从一个加上这个数字减去这个数字,你就得零。如果低于这个数字,你会得到一个如预期的那样。然后尝试2 ^ 51 = 2,251,799,813,685,248,并从2或3加上这个数字减去这个数字,你就得零。但是,如果你从4加上这个数字减去这个数字,你得到4.依此类推。
请注意,您的2E + 15值介于这些值之间,因此不会记录1的差异,但会有更大的差异。
本文明确解释了这一点: https://en.wikipedia.org/wiki/Double-precision_floating-point_format