Excel:输入的数字与显示的数字与内存中存储的数字

问题描述 投票:0回答:3

Excel 如何确定要显示的内容?特别是小数位数

例如:

50.98,存储为单精度浮点数时为 50.979999542236328125

50.979999 也存储为完全相同的单精度浮点数

(二进制表示。01000010010010111110101110000101,取自此处:https://www.h-schmidt.net/FloatConverter/IEEE754.html

当我在 2 个单元格中输入 50.98 和 50.979999 时,将格式更改为数字,并使用格式按钮扩展小数位

它准确地代表了我最初输入的 50.98 和 50.979999。

效果如何? Excel 是否存储了我输入的确切文本,而不是(直接)存储浮点数据类型?

如果它将其存储为双精度数,那么它如何保留我最初在这种情况下输入的精确精度?

我找不到概述其工作原理的文档。

请注意,它不会给我带来任何问题,我只需要解释 excel 显示方式与基于这些值的计算方式之间的差异。

excel floating-point
3个回答
1
投票

它准确地代表了我最初输入的 50.98 和 50.979999。

Excel 在 15 个有效小数位后用零填充。

内部数字以足够高的 binary 精度进行编码,从而将输出限制为 15 个 deimcal 位,原始输入的十进制值 appear 正是如此。


=2/3
是一个信息丰富的示例,显示了此限制,并通过一次仔细地提取一点来暴露二进制内部结构。

如一个单元格中所示,小数输出四舍五入到 15 位,之后用零填充。

0.66666666666666700000000

下面对

=2/3
进行二进制转换并形成 0.101010101010101010101010101010101010101010101010101012,这正是 Excel 使用 binary64 所期望的结果。 (下)

OP 的观察结果与使用 binary64 并将输出作为十进制文本四舍五入到 15 个有效数字是一致的。


Cell A3: =FLOOR(B2*A$1,1), Cell B3 = =B2*A$1 - A3


0
投票

假设:显示数字时,Excel 首先将数字转换为最多 15 位有效数字的十进制数字,即使需要更多有效数字。如果需要额外的数字,则将其填为零。 (此外,Excel 可能会根据上下文应用其他更改。)

在 Microsoft Excel 2008 for Mac 中,我在 A1 中输入

=1+22*POWER(2,-52)
,在 A2 中输入
=1+23*POWER(2,-52)
。使用 IEEE-754 二进制 64,这些应该生成数字 1.000000000000004884981308350688777863979339599609375 和 1.0000000000000051070259132757200859487056732177734 375.在B1和B2中输入
=A1-1
=A2-1
并将其设置为30位小数的数字格式,显示“0.000000000000004884981308350690”和“0.000000000000005107025913275720”,与IEEE-754一致64.因此我们可以确信上面的数字确实是生成并存储在 Excel 中的。

将A1和A2设置为20位小数的数字格式,显示“1.00000000000000000000”和“1.00000000000001000000”。

显然,如果 Excel 显示 20 位小数的实际数字,它将显示“1.000000000000004885”和“1.000000000000005107”。它不是。我们看到的显示与使用 15 位十进制数字(有效数字,不仅仅是小数点后面的数字)转换数字然后用零填充是一致的。

将 50.98 转换为 IEEE-754 二进制 64 格式会得到 50.97999999999999687361196265555918216705322265625。用 15 位十进制数字显示此结果为 50.9800000000000。


0
投票

需要注意的是,浮点不精确发生在计算过程中,而不是存储过程中。 您的 50,98 实际上存储为 5098*10e-2,您可以将其转换为二进制并返回,而不会丢失精度。

您可能会以迂回的方式谈论的精度损失发生在计算中,尤其是除法时。就像您无法将某些数字除以 3 并精确地写入它们一样(4/3 不是 1.33,对吧?),您也无法在不损失精度的情况下除以大多数二进制数字。如此简单的 1/5,也就是以 10 为基数的 0,2(存储为 2*e-1),变成了二进制的 0.0011...。但计算机只能用有限的“个”来表示数字,因此它会转换回十进制的 0.200000000000000011102。

这就是导致浮点数出现各种问题的原因,而不是在单元格中写入“50.98”:)

© www.soinside.com 2019 - 2024. All rights reserved.