我有一个简单的问题,但是因为我使用的这种“编程语言”是 32 位的,并且只支持加减乘除和串联(字面意思就是这样)等基本功能,所以我遇到了一些麻烦。
对于输入,我有一个 16 位数字,如下所示:3334,5678,9523,4567
然后我想从这个数字中减去 2 个其他随机的 16 位数字,并检查第一个和最后一个数字是否为 1。
例如,如果另外两个数字是 1111,1111,1111,1111 和 1234,5678,9123,4565。
我的最终号码是:0988,8888,9288,8891。
在这里,最后一个数字是 1,但第一个数字是 0,所以测试会失败。
问题在于 32 位系统,由于位提供的精度不够,存在大量错误。有什么方法可以绕过这个问题?
那是一个 16 位的十进制数。
这不是一个新的或“独特的” 问题,通常用 BCD 或多字整数来解决。
强调大范围幅度超过精度的浮点通常不适用于解决方案,因为(二进制)双精度要求多达 16 个(十进制)有效数字,但对于小数部分不准确(即 1/10 是无限的)二进制分数就像 1/3;见这篇文章)。
BCD(二进制编码的十进制)字符串允许无限精度(即位数)。
一些处理器甚至具有促进 BCD 算术的机器指令。
对于金融应用程序,有使用 BCD 算法的十进制(不是二进制)计算机。
具有N位字长的二进制计算机不受N位整数的算术限制。ALU
的进位和借位标志便于多个字的算术运算。 请参阅“使用进位位和溢出位的原因”的答案。
计算密集型程序可能更喜欢多字整数或定点解决方案以获得速度优势。
输入/输出密集型程序(例如计算器)可能更喜欢 BCD 整数或定点解决方案以获得转换优势。四功能手动计算器通常使用 BCD(而不是二进制)算术。
附录
上面提到的两种方案可以组合成一个混合方案。
使用 32 位整数 a
binary-coded billion
可以代替(未打包的)字节和 abinary-coded decimal
。不使用字节来存储 0 到 9(含)之间的解压缩值,而是将 BCD 的概念扩展为使用 32 位整数来存储 0 到 999,999,999(含)之间的值。
要表示 16 位十进制数,
binary-coded billion
需要两个 32 位字。此存储要求与使用 64 位整数时相同。
二进制和十进制基数之间的转换比纯二进制多字快,而算术比 BCD 快。
这种混合方案继承了其起源的优点。