前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《计算机系统基础》—— 运算

《计算机系统基础》—— 运算

作者头像
小点点
发布2023-03-06 13:29:49
4370
发布2023-03-06 13:29:49
举报
文章被收录于专栏:小点点

文章目录

《计算机系统基础》——运算

🚀🚀本章我们需要介绍的是有关C语言里面的运算,当然了,我们不会是介绍简单的运算,而是详细地介绍一下我们在日常开发中进行运算时可能遇到的问题。好了就让我们开始今天的学习吧!

整数

按位运算

作用

🚀🚀按位运算在我们日常的开发中出现的比较少,他的作用主要就是对位串实现“掩码”(mask)操作或相应的其他处理,比如在嵌入式领域一般用来控制寄存器的值,以达到相应的功能。

操作
  • 按位或:“|”
  • 按位与:“&”
  • 按位取反:“~”
  • 按位异或:“^”

🚀🚀比如用下面的语句用“&”实现“掩码”操作,作用为从数据y中提取低位字节,并使高字节为0。

代码语言:javascript
复制
y & 0x00FF

位移运算

🚀🚀一提到移位操作,很多人就是觉得只是用来乘除2的,但是事情并没有那么简单,接下来我们来详细的介绍一下。

作用

🚀🚀位移运算在我们的日常开发中一般都是用来乘除2的,但是它不仅仅只有这一个功能,除此之外,它还可以提取部分信息。

操作
  • 左移: x<<k(乘2)
  • 右移: x>>k(除2)
    • 逻辑右移:在左边补k个0
    • 算数右移:在左边补k个最高位的有效数字

🚀🚀我们在下方给出关于逻辑右移和算数右移的例子来帮助大家理解。

操作

值1

值2

参数x

[01100011]

[10010101]

x << 4

[00110000]

[01010000]

x >> 4(逻辑右移)

[00000110]

[00001001]

x >> 4(算数运算)

[00000110]

[11111001]

🚀🚀如果位移数大于数据位数怎么办呢?答案很简单,会对数据取余,比如对32位数据右移36位,其实就是右移4位。

乘法运算

🚀🚀在高级语言中,两个n位整数相乘得到的结果通常也是 一个n位整数,也即结果只取2n位乘积中的低n位

🚀🚀比如:0101 * 0101 = 00011001,我们只取后4位,得到1001,经过换算,结果应该是-111,也就是-7,显然与我们想要得到的数字明显不一样。

🚀🚀那我们有没有什么办法去判断我们的结果是否是正确的呢?或者说,到底什么情况下结果不会溢出?答案是肯定的,我们接下来就来介绍一下。

🚀🚀判断我们最后的结果是正确的,我们可以使用下面的语句去判断:

代码语言:javascript
复制
当 !x || z/x==y 为真时

🚀🚀然后当我们的结果在:-2n-1 ≤ x*y < 2n-1 时,结果是不会溢出的,其实也就是:乘积的高n+1位为全0或全1,这样的结果就是正确的。


🚀🚀整数乘法运算比移位和加法等运算所用时间长,因此,编译器在处理变量与常数相乘时,往往以移位、加法和减法的组合运算来代替乘法运算,所以我们可以使用位移来代替乘法指令,比如x * 20,因为20 = 16 + 20 = 24 + 22 ,所以我们可以转换为(x<<4)+(x<<2)。

除法运算

🚀🚀除法运算和乘法运算其实是类似的,但是只有带符号整数进行**-2n-1/-1 = 2n-1**操作会发生溢出之外,其他都不会溢出,因为2n-1无法用n位来表示。

代码语言:javascript
复制
#include<stdio.h>

void main ()
{
    int u = 0x80000000; 
    printf ("u = %x = %x = %d\n", u , u / -1, u / -1);      
}

🚀🚀运行结果如下所示:u = 80000000 = 80000000 = -2147483648,我们可以看到,在16进制下,u和u / -1 的结果是一样的。

🚀🚀除法运算的商为整数,于是如何进行取整就很重要了,我们只需要记住一个原则,就是按照朝0的方向舍入。即正数商取比自身小的最接近整数,负数商取比自身大的最接近整数

🚀🚀同样的,为了缩短除法运算的时间我们可以采用右移运算来实现。如果能整除,我们就直接右移,如果不能整除,我们就可以加一个偏移量(2k -1),再右移即可,接下来我们就来介绍一下。

代码语言:javascript
复制
14/4 = 3  ; 0000 1110 >> 2 = 0000 0011
-14/4 = 1111 0010 + 0000 0011 ;1111 0101 >> 2 = 1111 1101 = -3

浮点数

🚀🚀对于浮点数,我们就不做过多的介绍,简单介绍一下运算以及其异常,但是浮点运算涉及的精度以及异常是非常重要的,有机会以后可以单独介绍一下,

加减运算

🚀🚀对于浮点数的加减运算,我们只需要注意,他是先对齐阶码,再进行运算,如下所示:

A ± B = (Ma + Mb* 2-(Ea-Eb)) * 2Ea (假设Ea>=Eb )

🚀🚀需要注意的就是,当我们的尾数高位为0,则需左规:尾数左移一次,阶码减1,直到MSB为1。当尾数最高位有进位,需右规:尾数右移一次,阶码加1,直到MSB为1

乘除运算

🚀🚀乘除运算就需要注意阶码上溢(一个正指数超过了最大允许值)和下溢(一个负指数超过了最小允许值)的问题。过多的就不再介绍了,感兴趣的同学可以自行去查找资料。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-03-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 《计算机系统基础》——运算
    • 整数
      • 按位运算
      • 位移运算
      • 乘法运算
      • 除法运算
    • 浮点数
      • 加减运算
      • 乘除运算
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档