深入理解计算机系统读书笔记——信息的储存与运算——整数补码反码与原码

顺带说一个奇技淫巧

布尔代数

异 或 ⊕ 运 算 a ⊕ a = 0 异或\oplus 运算 a\oplus a = 0 aa=0
a ⊕ 0 = a a\oplus 0 = a a0=a
可以知道异或运算的每个逆元都是他本身,并且满足交换律和结合律,可以知道这是一个阿贝尔群…学过抽代的应该明白啥意思,我们知道异或运算有一个奇技淫巧来交换两个值
a 1 = a ⊕ b , a_1 =a \oplus b, a1=ab,
b 1 = a 1 ⊕ b , b_1= a_1\oplus b, b1=a1b,
a 2 = a 1 ⊕ b 1 a_2=a_1 \oplus b_1 a2=a1b1
下面来解释一下,其实只要把上面三个式子合在一起就可以了。
a = ( a ⊕ b ) ⊕ ( a ⊕ b ) ⊕ b a = (a\oplus b)\oplus (a \oplus b)\oplus b a=(ab)(ab)b
我们知道对于这个阿贝尔群来说逆元是本身,这样产生了单位元。

整数的表示方式原码,反码与补码

原码

假设电脑为8位字长,第一位0表示正,1表示负
1的表示
[0000 0001]
-1的表示
[1000 0001]

原码的问题

1 + -1 = [0000 0001] + [1000 0001] = -2
这显然不合理

反码

对于正数来说反码就是其本身

对于负数来说反码是符号位不变其余每一位取反

1的反码表示
[0000 0001]
-1的反码表示
[1111 1110]
1 + -1 = [1111 1111] 再取反 [1000 0000] 也就是-0
这样显然就会导致一个问题,也就是0我们有两种表示方法

同余

1 ≡ 11 m o d    10 , 意 思 是 说 1 和 11 除 10 的 余 数 一 样 都 是 1 1\equiv 11\mod 10 ,意思是说1和11除10的余数一样都是1 111mod10,111101
a ≡ b m o d    c ⇒ ( a + c ) ≡ b m o d    c 这 个 应 该 好 理 解 吧 a\equiv b\mod c \Rightarrow (a+c)\equiv b\mod c 这个应该好理解吧 abmodc(a+c)bmodc
− 1 ≡ 9 m o d    10 , 对 于 负 数 来 说 只 要 加 上 c 让 它 变 正 数 就 可 以 了 -1\equiv 9\mod 10,对于负数来说只要加上c让它变正数就可以了 19mod10,c

在看看取反码,假设为8位操作系统,对于符号位,我们相当于说对 2 8 2^8 28取同余,而数值大小位也就是前7位,我们相当于说对 2 7 2^7 27取余数
先看看正数

4 ≡ 2 7 + 4 m o d    2 7 , 4\equiv 2^7+4 \mod 2^7 , 427+4mod27,

再看看负数

− 4 ≡ 2 7 − 4 m o d    2 7 , -4\equiv 2^7-4 \mod 2^7 , 4274mod27,
这就是负数取反码的原理为啥符号位不变,其余位全部取反

那么为什么符号位不变呢?我认为这是有原因的

对于8位操作系统来说,我们能表示的 0 − 2 7 0-2^7 027已经拿来表示正数了,
而对于负数 0 到 − 2 7 0 到 -2^7 027我们相当于说要加上 2 8 边 正 数 再 对 2 8 进 行 取 余 2^8边正数再对2^8进行取余 2828
2 8 − 2 7 2^8 -2^7 2827
对于正数来说也是如此,但正数也就会发生溢出
2 8 + 2 7 2^8 + 2^7 28+27
所以导致了符号位不变,而这也是我最开始所说的对于符号位,我们相当于对8位操作系统进行操作,而数值大小相当有7位

补码

对于正数来说,补码是其本身

对于负数来说,补码是其反码再加1

到补码这里就没有任何问题了,补码存在的意义是为了解决+0和-0的问题,我们在负数反码的基础上加1其实缩短了[1000,0001]相当于说缩短了负数的表示范围 从
− 2 7 — — − 0 变 为 − 2 7 — — − 1 加 上 一 位 后 让 多 的 那 个 溢 出 了 -2^7 ——-0 变为 -2^7 ——-1 加上一位后让多的那个溢出了 270271

最后你可以做一个小实验,体验下

#include<iostream>
using namespace std;

int main()
{
	int a;
	//这里a输入一个比较大的数比如1432443
	cin>>a;
	a = short(a);
	//这里强制类型转换可能会出现负数,因为符合位的缘故
	cout<<a<<endl;

	return 0;
}

最后变成的时候做一个小总结:
int 类型不代表整数加法群,因为会有溢出现象;
double或者float也不能表示实数加法群,不仅仅有溢出,还有精度问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值