ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

6 信息的表示和处理_整数运算

2022-09-16 20:30:33  阅读:260  来源: 互联网

标签:运算 符号 处理 相加 补码 整数 溢出 乘法


目录
有趣的现象:计算机里,两个正数相加会得出一个负数,两个负数相加得出一个正数。为什么呢?看完这章就理解了。

1 无符号数加法

无符号数加法的数学**:

举例验证:
考虑一个4位数字的表示,x=9 和 y =12 的位表示分别是[1001]和[1100],他们的和是21。5位的表示为[10101]。此时就发生溢出了。如果丢弃最高位,得到[0101],即十进制的5。 5=9+12-2^4

等同于:

对于可以用x个位表示的两个无符号数,如果没有溢出,相加结果等于他们的和。如果有溢出,结果为两数之和减去2^x

在C中,无符号数相加,不会将溢出作为错误发出信号,需要自行判断是否溢出。
检测溢出
两个无符号数相加,如果结果少于两个中较大的那个数,那就意味着发生了溢出。

2 补码加法

补码加法的数学推论:

解释下:

  • 正溢出:正数相加,得到负数结果
  • 负溢出:负数相加,得到正数结果

举例子验证:对于用4个位表示的两个有符号数:

x y x+y 截断后 溢出情况
-8:[1000] -5:[1011] -13:[10011] 3:[0011] 负溢出
-8:[1000] -8:[1000] -16:[10000] 0:[0000] 负溢出
-8:[1000] 5:[0101] -3:[1101] -3:[1101] 正常
2:[0010] 5:[0101] 7:[0111] 7:[0111] 正常
5:[0101] 5:[0101] 10:[01010] -6:[1010] 正溢出

等同于:

对于可以用x个位表示的两个有符号数,相加后:

  1. 如果没有溢出,结果等于他们的和。
  2. 如果有正溢出,结果等于和减去2^x
  3. 如果有负溢出,结果等于和加上2^x

检测溢出:

  • 正数相加,得到负数结果,表明发生正溢出
  • 负数相加,得到正数结果,表明发生负溢出

4 阿尔贝群理论

因为阿尔贝群理论,我们可以得出:

  1. (x+y)-x ,求值总能得到y,无论加法是否溢出
  2. (x+y)-y,求值总能得到x,无论加法是否溢出

5 无符号数乘法

无符号数乘法的数学公式:

等同于:

对于可以用n个位表示的两个无符号数:x,y,相乘并对结果保留n位。那么这个截断后的值等于 【x乘以y,然后对2^n取模求余】。

补充说明:

  1. 任意两个可用x个位表示的无符号数想乘,结果的位数最多可能为2x位。 例如[110] * [110] = [100100]
  2. C语言中,无符号乘法并定义为产生x位的值,等于2x位的整数乘积的低x位表示的值。【就是截断只保留低x位并作为结果】

6 补码乘法

无符号数乘法的数学推论:

等同于:

对于可以用n个位表示的两个有符号数:x,y,相乘并对结果保留n位。那么这个截断后的值等于 【x乘以y,然后对2^n取模求余,然后将转为补码】

todo 有符号数乘法的二进制如何实现的

7 无/有符号数乘法验证

8 乘以常数

了解一下背景:

  1. 整数乘法、除法运算指令慢,需要耗费更多的时钟周期。
  2. 位运算需要耗费的始时钟周期少。
  3. 用位运算和加法运算的组合来代替常数的乘法运算。左移

无符号数乘以2^n,等价左移n位

例如,假设一个程序包含表达式x*14。利用14=2³+2²+2¹,编译器会将乘法重写为 (x<<3)+(x<<2)+(x<<1),将一个乘法替换为三个移位和两个加法。无论x是无符号的还是补码, 甚至当乘法会导致溢出时,两个计算都 会得到一样的结果

更好的是,编译器还可以利用属性14=24-21,将乘法重写为(x<<4)-(x<<1) ,这时只需要两个移位和一个减法。

9 除以2的幂

1、对于无符号数
数学推论:

等同于:

无符号数用逻辑右移实现除以2^n

验证:
16/2^2 =[0001 0000] >>>2 =[0000 0100] = 4

2、对于补码
数学推论:

等同于:

  1. 当补码为负数时,移位前加一个偏置(1<<k)-1,然后再进行算术右移
  2. 当补码是正数时,跟无符号数规则一致。

注意,除以2的幂我们可以通过逻辑或算术右移实现,但是与乘法不同,该方法不能推广到除以任意常数。

10 关于整数运算的最后思考

  1. 计算机执行的“整数”运算实际上是一种模运算形式。 改为【位运算】更容易理解
  2. 表示数字的有限字长限制了可能的值的取值范围,结果运算可能溢出
  3. 补码表示提供了一种既能表示负数也能表示正数的灵活方法,同时使用了与执行无符号算术相同的位级实现,这些运算包括像加法、减法、乘法,甚至除法,无论运算数是以无符号形式还是以补码形式表示的,都有完全一样或者非常类似的位级行为。
  4. C语言中的某些规定可能会产生令人意想不到的结果,而这些结果可能是难以察觉或理解的缺陷的源头。【unsigned数据类型 很坑爹
  5. 我们特别看到了unsigned数据类型,虽然它概念上很简单,但可能导致即使是资深程序员都意想不到的行为。我们还看到这种数据类型会以出意料的方式出现,比如,当书写整数常数和当调用库函数时。

11 阶段性总结

学习完 《4 信息的表示和处理_信息存储》、《5 信息的表示和处理_整数表示》《6 信息的表示和处理_整数运算》 这三节后,应该有以下的收获:

  1. 数据的表示、数据的运算的底层实现。
  2. 补码?因为有符号数的缺陷,引入了用补码来实现有符号数(正数或者负数)
  3. 为什么会产生溢出?因为字节数是固定的,比如只分配2个字节来存储整数,如果相加结果需要用3个字节才能存储,此时就会产生溢出
  4. 为什么两个正数相加的结果可能是负数?因为溢出,产生了截断。

标签:运算,符号,处理,相加,补码,整数,溢出,乘法
来源: https://www.cnblogs.com/knowledgeispower/p/16701136.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有