【发布时间】:2013-06-30 19:41:36
【问题描述】:
EDU>> intmin
ans =
-2147483648
EDU>> abs(intmin)
ans =
2147483647
这怎么可能?一定有某种溢出,或者这些函数的定义以奇怪的方式混合在一起。
【问题讨论】:
-
检查 Two's complement 和 32 位数字的范围。
EDU>> intmin
ans =
-2147483648
EDU>> abs(intmin)
ans =
2147483647
这怎么可能?一定有某种溢出,或者这些函数的定义以奇怪的方式混合在一起。
【问题讨论】:
对于 2 的补码 32 位有符号整数,intmin 是 0x80000000,或者实际上是 -2147483648。但是,intmax 是0x7FFFFFFF,也只是2147483647。这意味着intmin 的否定将是2147483648,它不能用 32 位有符号整数表示。
MATLAB 实际上做了一些奇怪的事情。在 2 的补码的正常规则下,0 - 0x80000000 应该再次给出0x80000000。但是,根据 MATLAB,0 - 0x80000000 = 0x7FFFFFFF。这应该可以解释为什么 abs(intmin) = intmax 适用于 MATLAB(但不一定适用于其他语言)。
不过,这种奇怪的东西有一个有趣的副作用:您可以假设 abs 永远不会返回负数。
【讨论】:
为了编码零,正/负二进制补码整数之间必须存在不对称性。
确实,您看到整数溢出(饱和)。
【讨论】:
对于每个integer 数据类型,都有一个可以用该类型表示的最大和最小数字:
当涉及整数的表达式的结果超过数据类型的最大值(或最小值)时,MATLAB 会将超出限制的值映射到最近的端点。这种saturation 行为解释了您所看到的,而不是二进制表示中overflow 的奇怪情况(在2 的补码中“环绕”)。
例子:
>> x = int8(100)
x =
100
>> x + x
ans =
127
【讨论】: