【发布时间】:2011-01-22 12:06:36
【问题描述】:
如果您不了解二进制,我知道 BCD 就像更直观的数据类型。 但是我不知道为什么要使用这种编码,因为它很浪费,所以它没有多大意义 以 4 位表示(当表示大于 9 时)。
另外我认为 x86 只支持直接添加和订阅(您可以通过 FPU 转换它们)。
这可能来自旧机器或其他架构?
【问题讨论】:
标签: assembly x86 cpu-architecture dataformat bcd
如果您不了解二进制,我知道 BCD 就像更直观的数据类型。 但是我不知道为什么要使用这种编码,因为它很浪费,所以它没有多大意义 以 4 位表示(当表示大于 9 时)。
另外我认为 x86 只支持直接添加和订阅(您可以通过 FPU 转换它们)。
这可能来自旧机器或其他架构?
【问题讨论】:
标签: assembly x86 cpu-architecture dataformat bcd
BCD 算法对于精确的十进制计算很有用,这通常是金融应用程序、会计等方面的要求。它还使诸如乘以/除以 10 的幂之类的事情变得更容易。现在有更好的选择。
有一个很好的Wikipedia article 讨论了利弊。
【讨论】:
BigDecimal 类型——如果你这样做肯定会很快。我不确定什么会比使用硬件数据类型“更好”。
BCD 在空间上是浪费的,这是真的,但它的优点是是一种“固定间距”格式,可以很容易地找到特定数字的第 n 位。
另一个优点是允许对任意大小的数字进行精确的算术计算。此外,使用提到的“固定间距”特性,可以轻松地将此类算术运算分块为多个线程(并行处理)。
【讨论】:
BCD 存在于现代 x86 CPU 中,因为它存在于原始 8086 处理器中,并且所有 x86 CPU 都与 8086 兼容。 x86 中的 BCD 操作在当时用于支持业务应用程序。处理器本身的 BCD 支持实际上已不再使用。
请注意,BCD 是十进制数的精确表示,而浮点不是,并且在硬件中实现 BCD 比实现浮点要简单得多。当处理器只有不到一百万个运行在几兆赫兹的晶体管时,这类事情就更重要了。
【讨论】:
BCD 在电子频谱的极低端非常有用,当寄存器中的值由某些输出设备显示时。例如,假设您有一个带有多个七段显示器的计算器,这些显示器显示一个数字。如果每个显示都由单独的位控制,那会很方便。
现代 x86 处理器将用于具有此类显示器的设备中似乎令人难以置信,但 x86 可以追溯到 很长 路,并且 ISA 保持了大量的向后兼容性。
【讨论】:
我确信前面链接到的 Wiki 文章更详细,但我在 IBM 大型机编程(PL/I 中)中使用了 BCD。 BCD 不仅保证您可以查看字节的特定区域以找到单个数字 - 这有时很有用 - 而且还允许硬件应用简单的规则来计算所需的精度和比例,例如将两个数字相加或相乘。
我记得,有人告诉我,在大型机上,对 BCD 的支持是在硬件中实现的,当时,这是我们表示浮点数的唯一选择。 (我们说的是 18 年!)
【讨论】:
30 多年前我上大学时,有人告诉我为什么 BCD(COBOL 中的 COMP-3)是一种很好的格式。
这些原因都与现代硬件无关。我们有快速的二进制定点算法。我们不再需要通过向每个 BCD 数字添加偏移量来将 BCD 转换为可显示的格式。我们很少将数字存储为每位 8 位,因此 BCD 每位仅占用 4 位这一事实并不是很有趣。
BCD 是遗物,应该留在过去,属于它的地方。
【讨论】:
我认为 BCD 对很多事情都有用,原因如上所述。似乎被忽略的一件显而易见的事情是提供从二进制到 BCD 的指令,反之亦然。这对于将 ASCII 数字转换为二进制以进行算术运算非常有用。
其中一个发帖人错误地认为数字经常以 ASCII 格式存储,实际上很多二进制数存储已经完成,因为它更有效。将 ASCII 转换为二进制有点复杂。 BCD 有点介于 ASCII 和二进制之间,如果有 bsdtoint 和 inttobcd 指令,它会使转换变得非常容易。所有 ASCII 值都必须转换为二进制以进行算术运算。所以,BCD 在 ASCII 到二进制的转换中实际上很有用。
【讨论】:
现在,通常以二进制格式存储数字,并将它们转换为十进制格式以供显示,但转换确实需要一些时间。如果数字的主要目的是显示或添加到将要显示的数字,则以十进制格式执行计算可能比以二进制执行计算并转换为十进制更实用。许多具有数字读数的设备和许多视频游戏都以压缩 BCD 格式存储数字,每个字节存储两位数字。这就是为什么许多分数计数器在 1,000,000 点而不是某个二次方值时溢出的原因。如果硬件不支持压缩 BCD 算术,则替代方案将不是使用二进制,而是使用非压缩十进制。在显示时将压缩的 BCD 转换为未压缩的十进制可以轻松地一次完成一个数字。相比之下,将二进制转换为十进制要慢得多,并且需要对整个数量进行运算。
顺便说一句,8086 指令集是我见过的唯一一个带有“ASCII 调整除法”和“ASCII 调整乘法”的指令集,其中一个将一个字节乘以 10,另一个将一个字节除以 10 .奇怪的是,值“0A”是机器指令的一部分,替换不同的数字会导致这些指令乘以或除以其他数量,但这些指令并未记录为通用乘法/除以常数指令.我想知道为什么没有记录该功能,因为它可能很有用?
注意到处理器用于加减压缩 BCD 的各种方法也很有趣。许多执行二进制加法,但使用标志来跟踪在加法期间是否从位 3 到位 4 发生进位;然后他们可能期望代码清理结果(例如 PIC),提供一个操作码来清理加法而不是减法,提供一个操作码来清理加法和另一个用于减法(例如 x86),或者使用一个标志来跟踪最后一个操作是加法或减法,并使用相同的操作码来清理两者(例如 Z80)。有些使用单独的操作码进行 BCD 算术(例如 68000),有些使用标志来指示加/减运算应该使用二进制还是 BCD(例如 6502 导数)。有趣的是,最初的 6502 以与二进制数学相同的速度执行 BCD 数学运算,但它的 CMOS 导数需要一个额外的周期来进行 BCD 运算。
【讨论】:
FBLD and FLSTP 来加载和存储 BCD 数字。一些现代架构具有对十进制浮点数的硬件支持,例如 Power6 和 IBM z10
很少有人可以计算以六进制表示的数量,因此以十进制显示或至少允许查看中间结果很有用。特别是在财务或会计领域。
【讨论】:
现代计算强调捕获设计逻辑的编码,而不是在这里或那里优化几个 CPU 周期。节省的时间和/或内存的价值通常不值得编写特殊的位级例程。
话虽如此,BCD 仍然偶尔有用。
我能想到的一个例子是当你有一个巨大的数据库平面文件或其他像 CSV 这样的 ASCII 格式的大数据时。如果您所做的只是在某些限制之间寻找价值,那么 BCD 就很棒。在扫描所有数据时转换所有值会大大增加处理时间。
【讨论】: