原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是 8 位二进制:
[+1] 原 = 0000 0001
[-1] 原 = 1000 0001
第一位是符号位. 因为第一位是符号位, 所以 8 位二进制数的取值范围就是:
[1111 1111 , 0111 1111]
即
[-127 , 127]
原码是人脑最容易理解和计算的表示方式.
反码的表示方法是:
正数的反码是其本身
负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.
[+1] = [00000001] 原 = [00000001] 反
[-1] = [10000001] 原 = [11111110] 反
可见如果一个反码表示的是负数, 人脑无法直观的看出来它的数值. 通常要将其转换成原码再计算.
补码的表示方法是:
正数的补码就是其本身
负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后 + 1. (即在反码的基础上 + 1)
[+1] = [00000001] 原 = [00000001] 反 = [00000001] 补
[-1] = [10000001] 原 = [11111110] 反 = [11111111] 补
对于负数, 补码表示方式也是人脑无法直观看出其数值的. 通常也需要转换成原码在计算其数值.
负数采用补码编码:例如 char t=-2,
原码是 1010,则反码是:1101,补码是:1110,即 - 2 的机器表示为 1110;
因为 c 语言中规定同级别的无符号数的精度高于有符号数,所以会隐式地将:有符号数转为无符号数(底层位级表示不变,只是解读方式不同)。
- #include<stdio.h>
- #include<stdlib.h>
- void main()
- {
- int a = -3;
- unsigned int b = 2;
- long c = a + b;
- printf("%ld\n",c);
- }
- A:-1
- B:4294967295
- C:0x7FFFFFFF
- D:0xFFFFFFFF
正确答案为:AB
解析:
无符号和有符号整数进行运算时,有符号整数会被提升为无符号整数。
-3 对应的二进制表示是 0xfffffffd,和 2 相加表示 0xffffffff。
输出结果取决于 long 是 32 位,还是 64 位。这个取决于编译器和机器。
long 是有符号的整型。
如果是 32 位,0xfffffff 在补码表示法(最高位是负数位)下是等于 - 1.
如果是 64 位,0xfffffff 是属于 long 的正整数范围(负数位在第 64 位),等于 4294967295。
(如果你的编译出来是 32 位的 long,你可以用 longlong 测试一下就能得到这个数。因为 long long 无论在 32 位机器或者 64 位机器都是占用 8 个字节 64 位)
来源: http://www.bubuko.com/infodetail-2452401.html