当前位置: 首页 > news >正文

3.整数运算

系列文章目录

信息的表示和处理 :

  1. Information Storage(信息存储)
  2. Integer Representation(整数表示)
  3. Integer Arithmetic(整数运算)
  4. Floating Point(浮点数)

文章目录

  • 系列文章目录
  • 前言
  • 一、无符号数的加法(Unsigned Addition)
  • 二、无符号数加法逆元
  • 三、补码的加法(Two's Complement Addition)
  • 四、补码的逆元
  • 五、乘法
  • 六、乘以常数(Multiply by Constants)
  • 七、除以2(Dividing by Powers of 2)
  • 总结
  • 参考文献:


前言

本文参考书籍是《深入理解计算机系统 3th 中文版》,本文的图片大多是参考和来自于b站up主九曲阑干。非常感谢大佬,侵权删。

本篇文章会提到部分整数数据和算数操作的术语,详情可见2.整数表示的前言部分。


一、无符号数的加法(Unsigned Addition)

先来看一个例子:

unsigned char a = 255;
unsigned char b = 1;unsigned cahr c = a + b;
printf("c = %d", c)

运行结果: c = 0
在这里插入图片描述
下面是这样一个无符号数加法的总结性结论:
在这里插入图片描述

考虑溢出,C 语言不会将溢出作为错误发出信号
当 x+y >= 2^w, 实际结果为 s = x+y-2^w
对任意的 x+y,s = (x+y) % 2^w

在这里插入图片描述
上述代码是判断是否溢出,证明略

二、无符号数加法逆元

根据逆元的定义好理解,但是从常识来讲不好理解
在这里插入图片描述在这里插入图片描述

三、补码的加法(Two’s Complement Addition)

在这里插入图片描述

正溢出:

char x = 127;
char y = 1;char z = a + b;
printf("z=%d", z);

运行结果:z = -128

解释:
在这里插入图片描述
负溢出:
在这里插入图片描述
如何判断溢出:
在这里插入图片描述

四、补码的逆元

这个知识点是没啥用又不太好理解的知识点,略过

五、乘法

正常的乘法:
在这里插入图片描述
无符号数的乘法:
在这里插入图片描述
补码的乘法:
在这里插入图片描述
举一个3-bit的乘法:

在这里插入图片描述可以看到,当相同的二进制位(binary)它们分别用不同的表示方式(无符号数,补码)相乘,在位层面上是一样的吗?
证明:
在这里插入图片描述在这里插入图片描述

六、乘以常数(Multiply by Constants)

在这里插入图片描述

相当于10进制里面移动小数点

为什么会这样???
在这里插入图片描述
举一个例子:
在这里插入图片描述

七、除以2(Dividing by Powers of 2)

在这里插入图片描述
在这里插入图片描述注意:补码和无符号数的右移
在这里插入图片描述证明略

这里有个特殊点:
在这里插入图片描述
这里我们期望得到的是-771而不是-772(直接向右算数移动四位)。

首先,我们为什么这么期望?因为有如下规则(向0舍弃):
在这里插入图片描述为了满足这种规则,如果x小于0,移位之前要加上一个bias
在这里插入图片描述这个bias的值是( 1 << k ) - 1
在这里插入图片描述


总结

  1. 无符号数加法可能会导致溢出
  2. 无符号数的加法逆元和补码逆元(鸡肋)
  3. 补码的加法:
    • 正溢出
    • 负溢出
  4. 无符号数的乘法,和补码的乘法
  5. 乘以常数,可以用左移。甚至可以拆分常数将其弄成2^k的组合形式
  6. 除以2^k
    • 正数就逻辑右移
    • 负数加上bias再算数右移(bias的作用就是使得结果向0舍入)
  7. 上面的乘以和除以2^k就可以用小数点移位去理解,就相当于是10进制中的乘和除以10^k

参考文献:

  1. 《深入理解计算机系统 3th 中文版》
  2. b站up主九曲阑干
http://www.lryc.cn/news/348261.html

相关文章:

  • uri.getQueryParameters(name)返回一个列表(List)
  • 鸿蒙ArkUI开发:常用布局【主轴】
  • Spring Security 入门 2
  • C++初阶学习第七弹——探索STL奥秘(二)——string的模拟实现
  • 5.nginx常用命令和日志定时切割
  • Redis-详解(基础)
  • 记录minio的bug(Object name contains unsupported characters.)
  • 【嵌入式开发 Linux 常用命令系列 7.6 -- sed 替换指定字符串】
  • C++语言的字符数组
  • 24届电信红队实习生面经
  • linux下使用jexus部署aspnet站点
  • 代码随想录训练营Day 27|理论基础、力扣 77. 组合
  • Spring框架深度解析:打造你的Java应用梦工厂
  • Python 正则表达式(一)
  • Cocos Creator 3.8.x报错:5302
  • 网页如何集成各社区征文活动
  • 【知识碎片】2024_05_13
  • Day53代码随想录动态规划part13:300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组
  • 自己动手为wordpress注册一个Carousel轮播区块
  • 基于Springboot的实习生管理系统(有报告)。Javaee项目,springboot项目。
  • 良心实用的电脑桌面便利贴,好用的便利贴便签小工具
  • Eayswoole 报错 crontab info is abnormal
  • 移动 App 入侵与逆向破解技术-iOS 篇
  • 2024服贸会,参展企业媒体宣传报道攻略
  • CI/CD笔记.Gitlab系列.新用户管理
  • 前端 JS 经典:JS 基础类型和 typeof
  • Java入门基础学习笔记11——关键字和标识符
  • 设计模式-解释器模式(Interpreter)
  • 机器视觉任务中语义分割方法的进化历史
  • Java并发编程: Synchronized锁升级