一、正负数的表示:
计算机只能存储01,正负数的存储有别!以最高位作为符号位:0=正数,1=负数!
正数的原码==反码==补码:
EG:10 =》 0000 1010
负数的原码,即将其正数表示的符号位,改为1:
EG:-10 =》 1000 1010
负数的反码,即其原码的符号位不变,其他位取反:
EG:-10 =》 1111 0101
负数的补码,即反码 + bit(1):
EG:-10 =》 1111 0101 + 0000 0001 = 1111 0110
二、任何数据都是以其二进制的补码形式存储在内存中的:因为计算机中只有加法没有减法,补码存储的数据其计算效率最高
下面我们看一个例子 这个例子也是我看的时候特别能帮助我理解的 清晰明了,例如 :
3 - 2; 这个减法运算对于计算机而言它的理解是 3 + (-2) = 1
使用原码计算:
3的原码 00000000 00000000 00000000 00000011
-2的原码 10000000 00000000 00000000 00000010
----------------------------------------------------
10000000 00000000 00000000 00000101 =》结果是1个负数明显是不对的
使用反码计算:
3 的反码: 00000000 00000000 00000000 00000011
-2的反码: 11111111 11111111 11111111 11111101
--------------------------------------------------
00000000 00000000 00000000 00000000 =》0
使用补码计算:
3 的补码: 00000000 00000000 00000000 00000011
-2的补码: 11111111 11111111 11111111 11111110
-------------------------------------------------
00000000 00000000 00000000 00000001 =》1
三、打印负数的补码,摘自:https://blog.csdn.net/wyt734933289/article/details/72889835
一个数的右移==算术右移,数学上表示除以2:如果是有符号数,对打印其 bit 不利,应先转为无符号数!
void main() {
int num[20], cnt = 0;
short a = -10;
unsigned short b = a;
while (b) {
num[cnt++] = b & 1; // 从最右边开始取位
b >>= 1; // 右移一位 == %2 =》左移== *2
}
for (int i = cnt - 1; i >= 0; i--)
printf("%d ", num[i]); // 倒叙输出
}
四、位运算
1.(int a) & 0x[0 | FF | xx] :将指定位清零,或者获取指定位!
2.(int a) | 0x[0 | FF | xx] :设定指定位=0|1;
3.(int a) ^ 0x[0 | FF | xx] :定位翻转,或者数值交换!
EG:要获取一个无符号数中从第 p 位开始的 n 位二进制数据(数据右端对齐)
unsigned int getbits(unsigned int x, unsigned int p, unsigned int n) {
unsigned int a, b;
a = x >> (p + 1); // a 右移 p+1 位(位计数从0开始)
b = ~(~0 << n); // ~0=全1,左移 n 位,再取反 == 右侧 n 位 1
return a & b;
}