在Excel中,当我输入22222.09482时,我会在编辑栏中看到22222.0948199999号


28

您能否提供帮助-因为我有一种奇怪的情况,当我在单元格中输入数字22222.09482时,我在公式栏中看到另一个数字22222.0948199999。下面是问题的快照。

样本误差

输入以下数字时,我会看到相同的行为:

22222.09482
33333.09482
44444.09482
55555.09482

但是当我输入11111.09482和66666.09482、77777.09482 ..直到99999.09482时,它们才能正确显示。我不确定这与舍入有关吗?我没有设置任何舍入配置文件。您能帮我解决这个问题吗?


1
整洁的发现,对我来说也一样-您能使用ROUND()吗?=ROUND(A1,5),然后将数据复制/粘贴为“值”并删除原始数字?
BruceWayne

1
@BruceWayne,有趣的是,ROUND()显示的数字正确,但是复制/粘贴的值将其带回到原始问题!
雷伊·朱纳

1
@ReyJuna-然后ROUND(A1,5)对粘贴的值再次进行。然后将其复制/粘贴为值,然后Round()再次复制/粘贴。...:P ...这很有趣,看起来@EugenRieck具有推理能力。好问题!
BruceWayne

1
您实际上是否在乎22222.09482和22222.0948199999之间的区别?相差100万亿分之5。
罗素·博罗戈夫

4
浮点数学运算是否被破坏?。但是,这可能是一个错误,因为它double具有足够的精度,因此在四舍五入时可以显示大多数人所期望的正确值
phuclv

Answers:


31

这是一个错误。

根据其他答案,Excel使用通常的IEEE双精度表示形式。其精度为53个有效二进制数字,大约相当于16个十进制数字。

显示前15个有效十进制数字始终是“安全的” 。从某种意义上说,可以安全地将任何用15位数字表示的十进制“表示”数字与通过将第15个十进制数字改成1而获得的数字区分开。例如,15位数字:

22222.09481 99999
22222.09482 00000
22222.09482 00001

映射到三个不同的双精度数字。在这种特殊情况下,这三个精度都不是双精度表示形式中的“邻居”。

因此,混淆用户显示中的前两个是Excel的错误。

实际上,在此域中(介于16384和32768之间),绝对精度为2 -38,并且可以表示以下数字:

...
22222.09481 99998 96571 9714760780334472656250000
22222.09481 99999 00209 9502831697463989257812500 <-- the one closest to what Excel showed to the user
22222.09481 99999 03847 9290902614593505859375000
22222.09481 99999 07485 9078973531723022460937500
22222.09481 99999 11123 8867044448852539062500000
22222.09481 99999 14761 8655115365982055664062500
22222.09481 99999 18399 8443186283111572265625000
22222.09481 99999 22037 8231257200241088867187500
22222.09481 99999 25675 8019328117370605468750000
22222.09481 99999 29313 7807399034500122070312500
22222.09481 99999 32951 7595469951629638671875000
22222.09481 99999 36589 7383540868759155273437500
22222.09481 99999 40227 7171611785888671875000000
22222.09481 99999 43865 6959682703018188476562500
22222.09481 99999 47503 6747753620147705078125000
22222.09481 99999 51141 6535824537277221679687500
22222.09481 99999 54779 6323895454406738281250000
22222.09481 99999 58417 6111966371536254882812500
22222.09481 99999 62055 5900037288665771484375000
22222.09481 99999 65693 5688108205795288085937500
22222.09481 99999 69331 5476179122924804687500000
22222.09481 99999 72969 5264250040054321289062500
22222.09481 99999 76607 5052320957183837890625000
22222.09481 99999 80245 4840391874313354492187500
22222.09481 99999 83883 4628462791442871093750000
22222.09481 99999 87521 4416533708572387695312500
22222.09481 99999 91159 4204604625701904296875000
22222.09481 99999 94797 3992675542831420898437500
22222.09481 99999 98435 3780746459960937500000000 <-- the one closest to what the user types
22222.09482 00000 02073 3568817377090454101562500
22222.09482 00000 05711 3356888294219970703125000
22222.09482 00000 09349 3144959211349487304687500
22222.09482 00000 12987 2933030128479003906250000
22222.09482 00000 16625 2721101045608520507812500
22222.09482 00000 20263 2509171962738037109375000
22222.09482 00000 23901 2297242879867553710937500
22222.09482 00000 27539 2085313796997070312500000
22222.09482 00000 31177 1873384714126586914062500
22222.09482 00000 34815 1661455631256103515625000
22222.09482 00000 38453 1449526548385620117187500
22222.09482 00000 42091 1237597465515136718750000
22222.09482 00000 45729 1025668382644653320312500
22222.09482 00000 49367 0813739299774169921875000
22222.09482 00000 53005 0601810216903686523437500
22222.09482 00000 56643 0389881134033203125000000
22222.09482 00000 60281 0177952051162719726562500
22222.09482 00000 63918 9966022968292236328125000
22222.09482 00000 67556 9754093885421752929687500
22222.09482 00000 71194 9542164802551269531250000
22222.09482 00000 74832 9330235719680786132812500
22222.09482 00000 78470 9118306636810302734375000
22222.09482 00000 82108 8906377553939819335937500
22222.09482 00000 85746 8694448471069335937500000
22222.09482 00000 89384 8482519388198852539062500
22222.09482 00000 93022 8270590305328369140625000
22222.09482 00000 96660 8058661222457885742187500
22222.09482 00001 00298 7846732139587402343750000
...

要进一步详细说明,请尝试22222.09482在一个单元格中键入,然后22222.0948199999在另一单元格中键入(五个尾随的9)。Excel应选择上面箭头指示的两个IEEE代表。我认为是的,因为您可以计算出这两个单元的差值9.82254E-11。但是两者的显示方式相同。

如果 Excel显示的是前 17位数字,那将有助于准确选择十进制数字“下方”的IEEE数字。在这种情况下:

22222.0948199999 --> 22222.09481 99999 00
22222.09482      --> 22222.09481 99999 98

但是,以错误的方式显示15位四舍五入会产生误导且无济于事。


在任何人声称这是故意的之前,那么为什么不8.7表现出相同的行为?最接近的双精度数8.7是:

8.69999999999999 93

因此应该表明8.69999999999999这是故意的。但事实并非如此。


9
没错,这是一个错误。转换显示最少有效数字位数的二进制浮点数的算法很困难,但是是已知的。好像有人错过了一些重要细节。
Mark Ransom '18

2
@Ruslan我在浮点算术,Stack Overflow和其他SE站点上看到了很多线程,通常人们会给出关于(二进制)浮点的各种一般性真理和概念的答案,而与实际数字无关并验证该行为是否符合IEEE。我想我可以提出一个问题:“为什么会2.1 + 2.2回来4.80000001?” 并得到许多答案,这就是我使用浮点数时必须期望的结果。
Jeppe Stig Nielsen

1
@benshepherd:LibreOffice屏幕截图没有显示Excel屏幕截图显示的内容
Thomas Weller

1
@JeppeStigNielsen:2.1 + 2.2 = 4.8?那只是0.5折。这是正常的。
Thomas Weller

@MarkRansom:那么,Excel真的可以自己实现吗?Excel不是用C ++来实现的,也不是为它计算浮点数的?那是你的意思吗 还是已经存在C ++中的错误,因此它影响了数百万个应用程序?
Thomas Weller '18

22

Excel以IEEE 754二进制64位浮点格式存储数字。关键是“存储”-从十进制到二进制的更改都会在存储数字时发生,而不仅仅是在实际计算中使用。

一篇不错的文章是“ 了解浮点精度”,又名“为什么Excel会给我看似错误的答案?”

可以制作一个电子表格程序来处理具有很多有效数字的非常大的数字。但这不是很实用。Excel 可以设计为使用IEEE 754 decimal128格式,该格式允许使用34个十进制数字-足以存储22222.09482。但取而代之的是,它使用更为通用的binary64 Double Precision格式,该格式具有53位精度,不足16位。尽管您可能认为只包含10位数字的数字就足够了,但从十进制转换为二进制会使事情复杂一点-即2222209482可以100%正确地存储为binary64数字,但是22222.09482不能。

请记住,通常电子表格用于财务数据,这通常不需要精度这么多的数字,或“假设”在各种场景,在不需要精确度的超高层建模研究。当然,还有其他工具(可能还有其他电子表格程序,但我最近没有搜索过),默认情况下或通过特殊配置设置可以使用更大的数字格式,但是Excel并不是其中一种。

对于那些指出LibreOffice可以更好地处理此问题的人来说,外观可能是骗人的。有关更多详细信息,请参见这篇文章。看起来LibreOffice处理大量数字的方式略有不同,但是具有相同的基本64位浮点表示形式,但存在类似的问题。


3
如果它也解释了这样的观察结果,那就更好了:一些带有小数的数字将完全按输入显示,例如OP示例中的11111.09482。
安德鲁

11
只是为了好玩:22222.09482存储1.0101101100111000011000010001100001111110011111000000₂ * 2₁₀^(10000001101₂ - 1023₁₀)在IEEE 754中,或者确切地说1.35632902954101553 * 2^1422222.0948199999984353787904
YoYoYonnY

1
Binary64(又名双精度)绰绰有余的十位小数号码。当然,它不能精确表示,但是大多数数字,包括0.20.1都不能精确表示(分数1/5(五分之一)具有无限的递归二进制扩展)。但是,Excel以一种混乱的方式显示事物。
杰普·斯蒂格·尼尔森

2
“请记住,通常电子表格用于财务数据,通常不需要那么多的精度” –这通常是非常错误的–财务数据需要精确的行为,即“您键入的内容是您期望的值” “,使用十进制/二进制转换等是正确的,但是此特定参数无效!对于财务数据,我们通常使用某种MoneyBigInteger格式,通常使用十进制存储格式。
Honza Zidek '18 -10-16

4
这个答案不足以解释会发生什么。我们正在观察Excel中的一个错误,该错误中的数字格式错误。22222.09482和22222.0948199999是不同的binary64数字。
Ruslan

11

在进行计算时,Excel需要为其使用的数字找到一个良好的内部二进制表示形式。在您的情况下,它使用浮点数,实际上,此数据格式与您的数字近似(非常好),但不完全匹配。因此,如果您没有明确告诉Excel使用哪种输出格式,它将“尽力而为”,从而导致输出的值更接近于内部计算的值,但并不完全是您输入的文本。

只是为了清楚起见:理解,您输入的文本表示一个数字,并将数字序列转换为数字已经满足上面的“计算”的定义。

编辑

我还没有说清楚,我认为选择使用64位浮点表示实际上是一个很好的选择:Excel并不是科学家的工具,因为小数点后第11位的舍入误差使得这是一个很大的影响,但是会计师不希望将处理速度降低数百万倍,以容纳可能会以他们从未使用过的数字体现出来的不精确计算的来源。

如果您将电子表格程序用于设计目的,并使用显式输出格式来确保这些效果永远不会进入可见范围,那么您会很好的。


1
评论不作进一步讨论;此对话已转移至聊天
DavidPostill

1
这个答案不足以解释会发生什么。我们正在观察Excel中的一个错误,其中该数字的格式错误。22222.09482和22222.0948199999是不同的binary64数字。
Ruslan

2

当我输入11111.09482和66666.09482、77777.09482 ..直到99999.09482时,它们将正确显示。我不确定这与舍入有关吗?我没有设置任何舍入配置文件。您能帮我解决这个问题吗?

一些数字可以正确表示,而有些则不能。

根据您的计算适当设置显示的精度,并使用round()函数。

  • 说明:

  • 解:

    在将数字格式应用于数据之前,可以通过设置“显示精度”选项来经常防止浮点舍入错误影响您的工作。此选项将工作表中每个数字的值强制为工作表上显示的精度。

    1. 单击文件>选项。
      在Excel 2007中:单击Microsoft Office Button Office按钮图像,然后单击Excel选项。
      按钮图片

    2. 单击“高级”,然后在“计算此工作簿时”下,选中“设置显示的精度”复选框,然后单击“确定”。

    3. 单击确定。

    4. 在工作表中,选择要格式化的单元格。

    5. 在“主页”选项卡上,单击“编号”旁边的“对话框启动器按钮”图像。
      启动器按钮图片
      Excel功能区图像

    6. 在类别框中,单击数字。

    7. 在“小数位数”框中,输入要显示的小数位数。

    提示:为了最大程度地减少浮点算术存储不准确的影响,您还可以使用ROUND函数将数字四舍五入到计算所需的小数位数。

  • 会计学期刊-“ 被Excel的计算错误所困扰 ”:

    某些奇数会创建重复的二进制小数,并且当这些重复的数字在15位后被截断时,该二进制数不会准确地转换回预期的数值。例如,在所有版本的Excel中,公式22.26-21.29应产生0.97,但得出0.970000000000002。尝试一下,并记住增加列宽和小数位,这样您就可以看到计算问题。

    此类错误通常被认为无关紧要或无关紧要,因为它们很少表现为有意义的计算错误。尽管如此,您可以采取以下两种措施来消除潜在的浮动小数点错误:

    1. ROUND功能。使用Excel的ROUND函数将您的计算值四舍五入到所需的小数位,从而消除了15位数字异常的可能性。例如,公式= ROUND(-21.29 + 22.26,2)准确得出0.97。

    2. 精确。您可以打开Excel的“显示精度”选项,以强制所有公式根据可见数字截断和舍入计算值。

    若要在Excel 2013、2010和2007中启用此选项,请选择“文件”(或Office Orb),“选项”(或Excel选项),“高级”,然后在“计算此工作簿时”部分中,选中“将显示的精度设置为”框,然后然后单击确定。

    在Excel 2003、2002和2000中,从“工具”菜单中选择“选项”,然后在“计算”选项卡上的“工作簿”选项下,选中“显示的精度”框,然后单击“确定”。


1
解释是无关紧要的:预期数字与获得的数字之间的差为28 ULP –对于自然舍入误差而言太大了。“解决方案”只是隐藏了一个真正的错误。
罗斯兰

如果您可以将其以及支持您答案的一些链接发布为您自己的答案而不是评论,那就太好了。这样,它将引起用户954171的注意,并且人们可以对其进行投票。您可以提供错误报告的链接吗?
罗布

已经有了所有相关数学细节的答案。Dunno对此有任何错误报告。
罗斯兰

0

如您所知,计算机内部仅使用零和一(也称为位),并且具有固定数量的位来表示一个值(如今通常为64位)。这意味着可以表示的不同值的数量是2到64的幂。当然,这是一个巨大的数字,但是可能值的数量是有限的,因此并非所有数字都可以表示。当遇到一个无法准确表示的数字时,它会自动替换为可以表示的最接近的数字。那就是你所看到的。


您是在说这是因为基数转换还是因为每个值的内存量有限?在这两种情况下,您的推理都是错误的。从技术上讲,假设内存无限,完全有可能具有任意精度和任意长度数。举个例子,有GNU bignum。此外,没有内在的需要以有损格式对数字进行编码。因此,计算机科学也不是错误,也不是二进制数。只有Excel开发人员选择了有损用户输入的数字编码。
菲涅尔

-1

计算机以二进制形式进行数学运算,并且几乎始终将浮点用于非整数值。只能在浮点数中精确表示的唯一小数值必须是2(1 / 2、1 / 4、1 / 8、1 / 16、1 / 32 ...)的小数幂的某种组合的和以设计的精度限制(通常为53位)。这些值并不总是用整齐的或精确的十进制表示,相反,并非所有可以精确用十进制表示的小数都将具有二进制的精确表示。例如:0.1。它不能表示为永远不会持续的2的小数幂之和。

当您在电子表格中输入一个十进制值时,它将被转换并以二进制形式存储,并且您所描述的情况将成为可以用二进制表示的最接近的近似值。显示时,它将转换回十进制,再次需要近似值,这可能无法转换回与您输入的完全相同的表示形式。

为什么要53位(给定或取)?因为存储“双精度”浮点的典型标准使用64位,所以其中有一个尾数(也称为有效数字),一个符号指示符和一个指数。指数通常分配10位,符号取1,尾数为53。这是用于存储。计算通常使用80位并四舍五入。

在某些情况下,计算机将以10为基数工作,特别是在使用无法取整工件的货币价值时。


2
我不同意所有计算机的声明。有许多计算机,使用十进制数字格式进行存储和计算,很可惜的是,除了用作博物馆零件之外,大多数计算机都不再处于活动状态。还有BCD(二进制编码的十进制)在许多较新的CPU中使用,包括在Intel CPU中的有限使用。这些都与手头的问题无关-Microsoft Excel用于存储数字的方法,它全为二进制。但是“所有计算机”是不正确的。
manassehkatz-恢复莫妮卡

我看到了从“所有计算机”到“计算机”的变化-我会选择“几乎所有计算机”或“大多数现代计算机”或类似的东西。我知道-我很挑剔。但是计算机也是如此:-)
manassehkatz-恢复莫妮卡

@manassehkatz所有数字计算机基本上都是二进制的。BCD只是二进制基础上的以10为基的结构,以方便十进制算术。
Zenilogix

尽管所有数字计算机从根本上来说都是二进制的,但实际上在早期有相当多的数字是基于十进制的。但是我同意BCD本质上是二进制基础上的以10为基的结构,以促进十进制算术。
manassehkatz-恢复莫妮卡

这个答案听起来好像是计算机的故障。但事实并非如此。您可以精确地表示可以在纸上书写的任何数字(精确表示1/3?例如,以小数形式存储时容易)。这实际上与Excel作者选择用哪种表示形式表示数字有关。
菲涅尔

-1

就像上面许多人所说的,这是一个内部表示错误。Excel已经选择了双精度,64位浮点数。这为您提供2 64个可能的值。实数域包含值的无穷大,因此当您尝试使用Excel不能表示的值时,它将使用可以表示的最接近值。

我看到有评论说,给定无限内存,任何实数都可以表示。是的,但是没有“无限内存”之类的东西,所以这是有争议的。其他人则说Excel可以使用较大的内部表示形式,例如128位。没错,但是事实证明,计算机更擅长对与处理器总线大小匹配的位数表示的数字进行数学运算。因此,一台32位计算机在32位数字上的数学运算最快,而一台64位计算机在64位数字上的数学运算最快。如果并且当将有一个128位计算机,那么我们可以期望Excel迁移到128位数字表示形式。这样仍然可以提供非常大但数量有限的一组数字。

如果您担心数字在电子表格中的外观,那么使用设置的精度(小数位数)将为您提供一致的结果。如果您担心键入的数字与Excel所存储的实际数字之间的差异,那么您会受到关注。差异是真实的,并且错误将通过您进行的任何计算得出。恐怕您会遇到此错误。这是Excel的局限性,不是某些人所说的错误。它不可能很快改变,因此,如果您不接受它,我建议您寻找另一个可以代表更高精度数字的电子表格应用程序。但是请记住,如果您找到任何此类应用程序,则限制仍然存在。只是错误的大小不同。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.