每个人都听过Bill Gosper 的这个笑话:
任何给定的编程语言都是机器独立的神话很容易通过计算 2 的幂和来打破。
- 如果结果以 period = 1 和符号 + 循环,则您在符号大小机器上。
- 如果结果在 -1 处以 period = 1 循环,则您在一个二进制补码机器上。
- 如果结果以句点 > 1 循环,包括开头,则您在一个补码机器上。
- 如果结果以句点 > 1 循环,不包括开头,则您的机器不是二进制的——模式应该告诉您基数。
- 如果内存不足,则说明您使用的是字符串或 Bignum 系统。
- 如果算术溢出是一个致命错误,那么一些具有只读头脑的法西斯猪正在试图强制执行机器独立性。但是捕获溢出的能力取决于机器。
通过这种策略,考虑宇宙,或者更准确地说,考虑代数:
让 X = 2 的多次幂之和 = ...111111
现在将 X 添加到自身;
X + X = ...111110
因此,2X = X - 1 所以 X = -1
因此代数是在一个二进制补码的机器(宇宙)上运行的。
我想我理解其他部分,但我被困在补语部分。我将考虑一个 3 位加一个符号位的简单示例。
bignum 和非二进制架构的行为很清楚。
如果结果以 period = 1 和符号 + 循环,则您在符号大小机器上。
当 2 的幂溢出到符号位时,它变为负零,因此添加它不会改变任何内容。下一次迭代,它完全消失了,我们一遍又一遍地添加正零,保持在MAXINT
.
例子:
______________________________
| Power of 2 || Accumulator |
| | ||Decimal|| | ||Decimal|
|0|001|| +1 ||0|001|| +1 |
|0|010|| +2 ||0|011|| +3 |
|0|100|| +4 ||0|111|| +7 |
|1|000|| -0 ||0|111|| +7 |
|0|000|| +0 ||0|111|| +7 |
|0|000|| +0 ||0|111|| +7 |
...
这确实是一个周期为 1 且为正值的循环。
如果结果在 -1 处以 period = 1 循环,则您在一个二进制补码机器上。
当二的幂溢出到符号位时,它产生最小的可表示整数。将其添加到
例子:
______________________________
| Power of 2 || Accumulator |
| | ||Decimal|| | ||Decimal|
|0|001|| +1 ||0|001|| +1 |
|0|010|| +2 ||0|011|| +3 |
|0|100|| +4 ||0|111|| +7 |
|1|000|| -8 ||1|111|| -1 |
|0|000|| +0 ||1|111|| -1 |
|0|000|| +0 ||1|111|| -1 |
...
果然,它在-1处循环。
如果结果以句点 > 1 循环,包括开头,则您在一个补码机器上。
那个,我想不通。我希望它应该去:
______________________________
| Power of 2 || Accumulator |
| | ||Decimal|| | ||Decimal|
|0|001|| +1 ||0|001|| +1 |
|0|010|| +2 ||0|011|| +3 |
|0|100|| +4 ||0|111|| +7 |
|1|000|| -7 ||1|111|| -0 |
|0|000|| +0 ||1|111|| -0 |
|0|000|| +0 ||1|111|| -0 |
...
我尤其看不到它如何在大于 1 的周期内循环。这意味着 2 的幂不是简单地由左移产生的(否则单个 1 位最终会下降),但是它们是如何计算的呢?