进制转换 && 位运算(包括补码、原码、反码、~0等一些零碎东西一次说清)

我发现网上关于标题上的内容介绍的都很零碎,因此为了方便查找、也为了本人对这一部分的充分理解,就想着写一篇这样的博客(我分成了几个部分,以便查找):

一、进制转换

让我们先来看看各个进制的定义

  • 十进制:就是我们平时很熟悉的,例如123、52、39等等;
  • 二进制:以0b开头(那是零,不是英文o,因为二进制英文是binary,所以是0b),例如:0b11(也就是十进制中的3);
  • 八进制:以0开头(零),例如015(也就是十进制的13);
  • 十六进制:以0x或0X开头(零、英文x或X),例如:0xF(也就是十进制中的15)。

了解了进制的定义,我们再来看看各个进制之间的转换(通常都是十进制与其他进制之间的转换):
先说十进制转换为其他进制:十进制数÷相应进制=商······余数→商÷相应进制=新的商······余数,直到 商 为0为止;然后把余数从右到左依次排列,就是相应进制的数了
计算机是以二进制存储的,所以我们主要说一下转换为二进制的:

举个例子,把11转换为二进制,过程:
11÷2=5······1,5÷2=2······1,2÷2=1······0,1÷2=0······1,所以二进制就是0b1011;
再来一个八进制的吧,把21转换为八进制,过程:
21÷8=2······5,2÷8=0······2,所以八进制就是025,
把35转换为十六进制,过程:
35÷16=2······3,2÷16=0······2,所以十六进制就是0x23,

我们再说说其他进制转换为十进制:举个例子大家就明白了,
把0b1011转换为十进制,过程:

  • 1×20 + 1×21 + 0×22 + 1×23 = 11

我们再来一个,把0x2AE转换为十进制:

  • 14×160 + 10×161 + 2×162 = 486

说完了这个,我们再来说说有关原码、补码、反码的一些东西

二、有关原码、补码、反码的一些东西

我们这里统一都以byte类型共8位 来进行说明:
我们都知道计算机是以二进制存储的,而且是以补码的形式存储的,而且:

  1. 正整数:补码 = 原码;
  2. 负整数:补码= 反码 + 1;
  3. 原码就是一个正整数的二进制,
  4. 反码是原码的符号位(即最高位,正数为0,负数为1)不变,其他各位取反(0变1,1变0);

废话不多说,举个例子大家就明白了,我们来看看9的源码,补码:
因为9是正数,所以补码=源码,根据上面的进制转换我们知道9的二进制是0b1001,所以以byte类型的存储方式就是:00001001,
所以 9的补码=源码=00001001
那-9的补码、源码、反码呢?
-9的源码就是符号位取1,其他各位与9的源码相同,所以就是:-9的源码=10001001,-9的反码=11110110,-9的补码=11110111,所以-9在计算机中以byte类型的存储形式就是11110111(-9的补码)
我们知道了十进制转换为原码,再转换为补码,那反过来呢?怎么由补码求出原码呢?
其实很简单,就是把上面的步骤倒过来就可以了,需要注意的就是:

  1. 如果补码的符号位(即最高位)为0,则为正数,此补码=原码;
  2. 如果补码的符号位为1,则表示负数,这时需要减1,再去反码,最后得到负数的原码。

我们来举个例子,补码为00101011,求其原码,
因为符号位为0,表示正数,所以该补码就是原码;
再来一个,补码为10101011,求其原码,
因为符号位为1,表示负数,所以先减1,得到10101010,再取反码 为11010101,这就是其原码,为负数

三、位运算(&、|、^、~)

位运算运算规则
& (按位与)全1则1,否则为0
| (按位或)全0则0,否则为1
^ (按位异或)相同为0,不同为1
~ (按位取反)遇0则1,遇1则0
<<(按位左移)将符号左边的数的二进制位依次左移(符号右边为移动位数)
>> (按位右移)将符号左边的数的二进制位依次右移(符号右边为移动位数)
  • 注意的一点是,按位异或的运算是可逆的,一个数按位异或另一个数两次,得到原数,例如6 ^ 9 ^ 9 = 6; 运用此特性,按位异或有一个很重要的作用就是:不使用临时中介变量,就可以直接交换两个值,
int num1 = 5, num2 = 6;
num1 = num1 ^ num2;
num2 = num2 ^ num1; //此时num2 = 5
num1 = num1 ^ num2; //此时num1 = 6

之所以会这样,我们来分析一下:num2 = num2 ^ ( num1 ^ num2 ) = num1 ^ ( num2 ^ num2 ) = num1 ^ 0 = num1,此时num2 == num1 == 5 ;
然后num1 = num1 ^ num2 = ( num1 ^ num2 ) ^ num2 = ( num1 ^ num2 ) ^ num1 = num2,此时num == num2 == 6;
而且我们要清楚( num1 ^ num2 ) ^ num2这个式子中第一个num2是原来的num2(即值为6),第二个num2已经是原来的num1(即值为5)了

  • 我们再来说一下0的按位取反(~0)为啥等于-1

    • 以byte类型来说明,0的补码为00000000,则~0后得11111111,我们要注意此时的11111111是在计算机中存储的,所以是补码形式,因为符号位位1,所以该数为负数,通过上面讲过的补码转换为原码的步骤,可得原码为10000001,该原码也就是十进制中的-1了
  • 1的按位取反(~1)为啥等于-2呢?

    • 其实跟上面的~0原理一样,我们同样以byte类型来说明,1的补码为00000001,按位取反后得到11111110,此时同样为补码的形式存储,减1、再取反后 可得原码为10000010,也就是十进制中的-2
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不动声色的小蜗牛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值