从近世代数的角度理解补码

介绍

模数加法形成了一种数学结构,成为阿贝尔群(Abelian group),这是以丹麦数学家阿贝尔的名字命名的。

前置知识

定义1. 设a,bZ,如果存在qZ使得a=qb,则称b整除a,记为b|a

定义2. 设a,bZb>0a=qb+rqZ0r<b,则称ra除以b所得到的余数,记为amodb

定义3. 设a,b,nZn>0,如果amodn=bmodn,则称abn同余,记为ab(modn)

定理1. a,b,nZ,n>0,ab(modn)等价于n|(ab)

定理2.

  1. aZ,aa(modn)
  2. a,bZ,如果ab(modn),则ba(modn)
  3. a,b,cZ,如果ab(modn)并且bc(modn),则ac(modn)
  4. a,b,kZ,如果ab(modn),则a+kb+k(modn)
  5. a,b,c,dZ,如果ab(modn)并且cd(modn),则a+cb+d(modn)
  6. a,b,kZ,如果ab(modn),则akbk(modn)
  7. a,b,c,dZ,如果ab(modn)并且cd(modn),则acbd(modn)
  8. a,bZabmodn=(amodn)(bmodn)modn

定义4. 设nZn>0xZ,定义[x]={y|yx(modn)},称为整数集Z上在模n同余的等价关系下的一个等价类。

例.

4同余关系的所有等价类为:

  • [0]={,8,4,0,4,8,}
  • [1]={,7,3,1,5,9,}
  • [2]={,6,2,2,6,10,}
  • [3]={,5,1,3,7,11,}

定理3. 设nZn>0x,yZ[x]=[y]当且仅当xy(modn)

模数加法构成阿贝尔群

  1. Zn={[0],[1],,[n1]}为整数集Z上在模n同余的等价关系下所有等价类之集。
  • Zn上定义加法运算“+”如下:

  • [i],[j]Zn,[i]+[j]=[i+j],则(Zn,+)构成一个交换群;

  • Zn上定义乘法运算“”如下:

  • [i],[j]Zn,[i][j]=[ij],则(Zn,)构成一个交换幺半群。

​ 证明:

  • i,j,i,jZ,如果[i]=[i][j]=[j],则[i+j]=[i+j],这验证了“+”为一个运算。

  • i,j,kZ([i]+[j])+[k]=[i+j]+[k]=[(i+j)+k][i]+([j]+[k])=[i]+[j+k]=[i+(j+k)]([i]+[j])+[k]=[i]+([j]+[k]),这验证了加法运算+满足结合律。

  • iZ[0]+[i]=[i]+[0]=[i],这验证了[0]为单位元。

  • iZ[ni]+[i]=[i]+[ni]=[n]=[0],这说明[i]有逆元。

    以上验证了Zn对于加法运算“+”构成一个群。

  1. Zn={0,1,2,,n1},在Zn上定义运算""如下:ij=(i+j)modn,则(Zn,)构成一个群。

​ 证明:

  • a,b,cZn,(ab)c=a(bc),结合律。

  • ((a+b)modn+c)modn=(a+(b+c)modn)modn

  • ((a+b)modn+c)modn=(a+b+c)modn

  • (a+(b+c)modn)modn=(a+b+c)modn

  • 0a=(0+a)modn=a

  • 如果a0,则(na)a=(na+a)modn=000=(0+0)modn=0

举例

设用n个二进制位表示一个整数xx的补码定义为:

  • 如果x0,则x的补码为x的原码;

  • 如果x<0, 则x的补码为x+2n的原码。

1:

设用8个二进制位表示一个整数,计算7-7补码

解:

  • 因为70,因此7的补码为7的原码,即7的补码为0000_0111。

  • 因为7<0,因此-7的补码为7+28的原码,即-7的补码为1111_1001。

7的补码还可以这样求解:

  • 先计算7的原码,得到0000_0111
  • 然后取反加1,得到7的补码为1111_1001。

例2:

设用8个二进制位表示一个整数,计算-128补码

  • 因为128<0,因此-128的补码为128+28的原码,即-128的补码为1000_0000。

  • 同样的,128的补码还可以这样求解:先计算128的原码,得到1000_0000,然后取反加1,得到128的补码为1000_0000。

如果用n个二进制位表示一个整数,用补码表示的数字的范围为2n12n11

对于补码而言:

  • 如果首位为0,其表示的是大于等于0的整数。
  • 如果首位为1,其表示的是负数。

例3

如果用8个二进制位表示一个整数,00001010为哪个整数的补码?10001010为哪个整数的补码?

  • 因为00001010的首位为0,它为一个大于等于0的整数的补码,这个整数为10
  • 因为10001010的首位为1,它为一个负数的补码,这个负数为13828=118

对补码加法的分类讨论

计算机中普遍采用补码表示数字的原因是对于负数的加法可以采用与自然数的加法一样的加法器 。

xy为任意的两个整数,分以下4种情况讨论:

x0y0

  • 此时x的补码为x的原码。
  • y的补码为y的原码。
  • 按照自然数相加计算得到x+y,恰为x+y的补码。

x<0y0

  • 此时x的补码为x+2n的原码。
  • y的补码为y的原码。
  • 按照自然数相加计算得到x+2n+y=(x+y)+2n
  • 如果x+y<0,则得到的恰为x+y的补码;
  • 如果x+y0,计算结果的第n位(从最右边数起,依次为第0位,第1位,,第n1位,第n位)会自动抛掉。这恰好就是在mod2n

x0y<0

  • 此时x的补码为x的原码。
  • y的补码为y+2n的原码。
  • 按照自然数相加计算得到x+(y+2n)=(x+y)+2n
  • 如果x+y<0,则得到的恰为x+y的补码;
  • 如果x+y0,计算结果的第n位会自动抛掉。

x<0y<0

  • 此时x的补码为x+2n的原码。
  • y的补码为y+2n的原码。
  • 按照自然数相加计算得到(x+2n)+(y+2n)=(x+y)+2n+2n,计算结果的第n位会自动抛掉,于是最终得到的计算结果为(x+y)+2n,恰为x+y的补码。

为什么是取反加一

相信大家一开始学习补码的时候都是记为取反加一,然而在看了本篇博客后,你或许明白了为什么是这样的。

x为任意一个8位有符号整数(char),也就是说它的二进制位数为8位。

x0

  • 此时x的补码为x的原码。

x<0

  • y=x,即yx的相反数,y为正数。
  • ay的二进制表示(原码),bx的二进制表示(补码)。
  • 那么由前面的知识,可以知道,ab 在模2n(n 为 二进制位数,这里为8)同余运算上,是互为逆元。
  • 那么,ab=(a+b)mod2n=(e)mod2n=0=(2n)mod2n
  • 所以,我们可以让a+b=2n。(让a+b=0是一样的,原因在下)。
  • 好,现在计算b
  • 对于一个n位二进制数,2n 表示为1_0000_0000 ,一共后面为n个0。(所以在计算机里,这个最高的1是不不存在的,是会被抛弃的,那么也可认为a+b=0
  • 现在我们如何凑出这个数?显然,a+a=1111_1111。(aan1)。
  • 则,a+a+0000_0001=1111_1111+0000_0001=1_0000_0000
  • 这时候b=a+0000_0001, 即取反加一。

补码的连续性

现在我们研究下 -1。

  1. 可以根据前面的知识,我们写出1 的二进制表示(8位)0000_0001
  2. 然后取反加一,得1111_1111
  3. 现在令1=e+(1)=0+(1)=01
  4. 而变为二进制表示后01=0000_00000000_0001
  5. 在第9位上,可以借1,所以 =1_0000_00000000_0001=1111_1111

补码这样的连续性使得我们在进行有符号数加减法时不需要考虑其他运算规则,直接相加即可。


负权

补码所表示的数,我们通常这样计算:

设表示的数为w ,二进制数表示为snsn1sn2····s2s1si(1in)sn为符号位。

  • 表示负数,sn=1w=2n1(1)+i=0n22i
  • 表示非负数,sn=0w=i=0n22i

表示非负数很好理解,就是进制转换

那么负数为什么要有负权呢?为什么最高位代表的权值是负的?

  • 如果最高位我们视为正权,得到的值记为ww=i=0n12i
  • 显然,由之前的理论可以知道,w(w)。即w+(w)=2n=0(mod2n)
  • 但是w+(w)=0=0(mod2n)相反数也是互为逆元。
  • 那么它两就是等价类啊。但是它两的二进制表示是一样的,只是计算的方式不一样。
  • 根据等价类的定理3, [w]=[w]当且仅当ww(mod2n)
  • 那么,因为w>w, 则w=w+2n。则w=w2n
  • 2n=2n1+2n1,也就说我们得减去个最高位的1。
  • 既然这样,令最高位的正权属性变为负权,不就正好是两个吗?
  • 所以,定义最高位为1时,为负权 。

为什么是补码?

现在,让你设计一个正数负数都可以表示的运算系统,你会想到令一位为标志位 (Flag),来特殊地表示这个数是正数还是负数。

那么,计算机科学家们是先想到这样的编程思想(Flag位),还是先由近世代数进一步研究发现的呢?

我认为是由近世代数这样的思想进一步推广研究发现的。

毫无疑问,补码这些性质奠定了计算机科学的基础。


后记

这篇博客主要参考我的近世代数老师的讲义,他在上课时说,他当时在研究生推免答辩就问为什么计算机中要用补码,结果没有人答得上来。

参考资料:王义和.离散数学引论[M].哈尔滨:哈尔滨工业大学出版社,2007

posted @   江水为竭  阅读(559)  评论(5编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示