学习位操作

        计算机中所有数据都是以二进制的形式储存的,运算直接对在内存中的二进制数据进行操作,因此处理数据的速度非常快。位操作只能用于整形数据,对float和double类型进行位操作会被编译器报错。

计算机底层保存的是补码,正数的原码等于补码

&:上下两位都是1是,结果为1

|:上下两位有一个是1,结果为1

当表示状态时,会用特定的数表示开关,比如文本四个状态:粗体(1)、斜体(2)、下划线(4)、中划线(8)转成二进制后按位或

粗体、斜体 = 0011 = 1 | 2

粗体、斜体、中划线 = 1011 = 1 | 2 | 8

~:按位取反:原来是0变1,原来是1变0;正数变成负的(绝对值+1),负数变成正的(绝对值-1)

  • 原码:10进制变2进制,8位,并标明符号位。0正数,1负数,最左一位为最高位。
  • 反码:按位取反
  • 补码:除符号位不变,其他位取反
  • 补码修复:最高位为正,末尾 -1 修复;最高位为负,末尾 +1 修复
  • 转换:2进制变10进制

补充:为什么要有补码及补码修正?因为计算机中减法是通过加一个负数处理的,而负数又是通过补码保存的。目的就是为了统一加法减法

按位取反后为什么正数变成负的(绝对值+1),负数变成正的(绝对值-1),举例说明:

~9 结果:-10
原码:00001001
反码:11110110
补码:10001001
修正:10001010 1是负,加1修正
转换:-0008020 -> 10

~-9 结果:8
原码:10001001
反码:01110110
补码:00001001
修正:00001000 0是正,减1修正
转换:+0008000 -> 8

我还想知道计算机的补码修复原理为什么最高位为正,末尾 -1 修复;最高位为负,末尾 +1 修复

于是找到一篇博客《补码原理的个人理解》https://blog.csdn.net/jiaobuchong/article/details/83188674

于是同余定理取模运算了解了一下

取模运算和取余运算区别:

主要的区别在于对负整数进行除法运算时操作不同

对于整型数a,b来说,取模运算或者求余运算的方法都是:

1.求 整数商: c = a/b;

2.计算模或者余数: r = a - c*b.

求模运算和求余运算在第一步不同: 取余运算在取c的值时,向0 方向舍入(fix()函数);而取模运算在计算c的值时,向负无穷方向舍入(floor()函数)。

例如计算:-7 Mod 4

那么:a = -7;b = 4;

第一步:求整数商c,如进行求模运算c = -2(向负无穷方向舍入),求余c = -1(向0方向舍入);

第二步:计算模和余数的公式相同,但因c的值不同,求模时r = 1,求余时r = -3。

归纳:当a和b符号一致时,求模运算和求余运算所得的c的值一致,因此结果一致。

当符号不一致时,结果不一样。求模运算结果的符号和b一致,求余运算结果的符号和a一致。

另外各个环境下%运算符的含义不同,比如c/c++,java 为取余,而python则为取模

回到正题:补码计算方式

       /  X       正数和 0 的补码,就是该数字本身
 [X]补 = |
      \ 模 -|X| 原码    X < 0 负数的补码,就是用模减去该数字绝对值的原码

在模一定的情况下,取模的结果就是我们想要的值。

计算机无法表示无穷大和无穷小的数字,无论何种数据类型都有一个上限和下限,超过了限定就会产生溢出。超出了上限就叫上溢出(overflow),超出了下限就叫下溢出(underflow)这不就是前面所讲的取模吗。所以计算机数值的溢出,就相当于取模,那我们前面所讲的同余的概念就可以在这个地方使用了。

很多教材会说负数的补码等于绝对值的原码取反加一,那这个又是怎么来的呢?
本文中说的补码的求法是:补码 = 模 - |x|(绝对值原码),比如要求 -7 的补码:

一个4位的二进制数能表示的数是有限的,从 0000 ~ 1111 ,0000表示0,1111表示 - 1,最大值7(0111),最小值-8(1000)

10000(模)- 0111 
= 1111 + 1 - 0111
= 1111 - 0111 + 1 (加法交换率)   // 1111 - 0111 这一步相当于取反
= 1000 + 1   // 于是可以得出 补码=绝对值的原码取反 + 1

 

所有的 x -y 都转换成 x + (-y)-y 用补码表示,直接将 x 的二进制和 -y 的补码二进制相加即可得到 x-y 的结果。

通过负数的补码将减法转换为加法,出现的进位就是模,舍去即可

4 - 2 = 2 
  0100
+ 1110
----------
 10010
这里出现了进位,舍去进位。
结果 10010 超过模了,其实舍去就相当于 10010 - 10000(类似mod M)= 0010,
溢出就相当于取模,
我们最后得到的结果就是取模的结果。

模是 m,在模的基础上,-a 和 m - a 对于模 m 同余,m-a 是 -a 的补码。于是计算机中用 m-a 表示 -a,x - a = x + m - a (模是 m ),溢出就相当于是在取模。所以这也是我理解为什么使用补码的原因,其实就是数学里「同余」的概念,你会发现我们操作的其实就是在进行取模运算,这是一个很精妙的算法,它规避了在计算机中进行减法器的运算
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值