Lew*_*rin 6 c c++ binary signed twos-complement
我还没有找到最低签名负数没有等效签名正数的原因?我的意思是在3位二进制数字中为简单起见100是-4?但我们不能在签名格式中得到积极的4,因为我们不能.它溢出来了.那么我们怎么知道两个补码1000是-4 1000 0000是-128等等?我们没有原始正数
tem*_*def 17
考虑它的一种方法是签名的二进制补码格式通过为每个位赋予2的幂,然后翻转最后2的幂的符号来工作.让我们看一下-4,例如,它表示为100.这意味着值是
-1 x 2^2 + 0 x 2^1 + 0 x 2^0
Run Code Online (Sandbox Code Playgroud)
如果我们想获得这个值的正面版本,我们必须否定它才能获得
1 x 2^2 - 0 x 2^1 - 0 x 2^0
Run Code Online (Sandbox Code Playgroud)
请注意,此值等于
1 x 2^2 + 0 x 2^1 + 0 x 2^0
Run Code Online (Sandbox Code Playgroud)
换句话说,这个值的正常二进制表示是100.但是,我们在这里遇到麻烦,因为我们使用带符号的二进制补码表示,这意味着我们专门保留了4位作为符号位.因此,当我们尝试将位模式100解释为带符号的三位二进制补码值时,它会与我们开始时的情况完全相同.比特的不足正是在这里受到伤害.
更一般地,给定n位,其中第一位是二进制补码表示中的符号位,尝试计算-1000 ... 00将返回相同的值,因为存储大正值所需的位具有特殊值分配给它的意思.
那为什么要这样呢?原因是如果你只有n位,你就不能存储值-2 n - 1到2 n - 1,因为这里有2 n + 1个不同的数字,只有2 ^ n个不同的位模式.因此,排除最大正数使得可以在指定的位模式中保存所有不同的数字.
但为什么要降低高价值而不是低价值呢?这是为了保持与无符号整数的二进制兼容性.在无符号整数中,值0到2 n-1 -1都使用标准的基数2表示法进行编码.因此,对于无符号和有符号整数完全一致,无符号整数的设计使得它们与前2 n - 1个无符号整数等位相同,其范围为0到2 n - 1 - 1,包括0和2 n - 1 - 1 .在此之后,无符号值需要最高位来编码数字,但有符号值使用此作为符号位.
希望这可以帮助!
oua*_*uah 13
-INT_MIN 是一个整数溢出,在C中是未定义的行为.
-INT_MIN保证INT_MIN仅在有符号整数溢出换行时才等于.gcc例如,-fwrapv可以使用选项启用此功能.
编译器通常利用整数溢出是C中未定义的行为以执行某些优化的事实.依赖于有问题的整数溢出,换行是不安全的.
编译器优化的一个众所周知的例子如下
#define ABS(x) ((x) > 0 ? (x) : -(x))
void foo(int x){
if (ABS(x) >= 0) {
// some code
}
}
Run Code Online (Sandbox Code Playgroud)
今天(gcc,icc)启用了优化选项的大多数编译器将依赖于-INT_MIN未定义行为的事实来优化测试.