美文网首页其他零散知识点
Java基础——原码、反码、补码 以及 位运算

Java基础——原码、反码、补码 以及 位运算

作者: Neo_zero | 来源:发表于2018-07-02 23:49 被阅读28次

有些工作几年的同学已经忘记了大学学过的计算机基础(没错,说的就是我),于是把一些基础的东西拎出来复习一下。

原码、反码、补码

首先要知道,计算机使用的是补码。为什么要用补码呢?慢慢往下看。

  • 原码

原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:

[+1]原 = 0000 0001
[ -1]原 = 1000 0001

第一位是符号位,所以8位二进制数的取值范围是[1111 1111,0111 1111],即[-127,127]。

  • 反码

正数的反码和原码相同,负数的反码为:符号位不变,数据位取反。

[+1]反= 0000 0001
[-1]反= 1111 1110

  • 补码

正数的补码等于原码。负数的补码等于反码+1。

[+1] = [0000 0001]原 = [0000 0001]反 = [0000 0001]补
[-1] = [1000 0001]原 = [1111 1110]反 = [1111 1111]补

计算机为什么使用补码?

对于人来说,可以理解符号位的概念,计算加减时会计算真值位。但是计算机并不理解符号位,需要设计一种符号位也可以参与加减的方法。同时减法可以转换成加法,于是对于计算机来说更简单了。

假设符号位参与运算,首先来看原码:
计算十进制的 1-1=0;

1 - 1 = 1 + (-1) = [00000001]原 + [10000001]原 = [10000010]原 = -2

很明显是错的。
现在用反码来运算:

1 - 1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原= [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0

从结果来看。真值部分是正确的,问题出在符号位。虽然我们知道-00都是0,但是这个-是没有意义的,怎么能干掉它呢?

来看补码的运算结果:

1-1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原 = [0000 0001]补 + [1111 1111]补 = [0000 0000]补=[0000 0000]原

很完美,结果是正确的,也没有符号位问题。
所以,计算机就用补码来表示数据啦。
使用补码, 不仅仅修复了0的符号以及存在两个编码的问题, 而且还能够多表示一个最低数. 这就是为什么8位二进制, 使用原码或反码表示的范围为[-127, +127], 而使用补码表示的范围为[-128, 127]。

计算机用补码,把符号位参与运算,这其中有什么数学原理呢?有兴趣的同学可以了解一下同余定理

位运算

Java里保留了二进制的位运算操作,日常开发中位运算不是很常用,但是巧妙的使用位运算可以大量减少运行开销,优化算法。

&:按位与。都为1时为1,否则为0
|:按位或。有一个为1时就为1,否则为0
~:非。取反
^:按位异或。相同为0,不同为1
<<:左位移运算符。左边溢出的被丢弃,右边补0
>>:带符号右位移运算符。正数时左边补0,负数时补1
<<<:无符号右移运算符。不考虑符号位,高位补0,低位溢出时丢弃

计算机怎么计算加法?

当然是用位运算实现的。

计算机计算二进制加法是分三部,第一步为将两个加数转换为二进制数,计算两个加数不需要进位的和(利用异或运算 ^ ),得出的结果。第二部将两个加数进行与运算(&)。第三部利用与运算得到结果进行左移运算(<<)(同时为计算两个加数需要进位的和),得出结果。将或异运算的结果和左移运算的结果作为两个新的加数,重复此操作。直到当与运算的结果为0,则异或运算的结果则为两个加数的和所对应的二进制数。

image.png

相关文章

  • Java基础——原码、反码、补码 以及 位运算

    有些工作几年的同学已经忘记了大学学过的计算机基础(没错,说的就是我),于是把一些基础的东西拎出来复习一下。 原码、...

  • [计基]-二进制之补码

    一.基础名词 原码 : 0011 反码 :0011(原码) >> 1100(反码) (原码按位取反) 补码 :00...

  • 原码、反码和补码

    正数的原码、反码和补码相同,亦是正数 负数的原码、反码和补码符号位为1,代表负数,反码在原码的基础上符号位不变,其...

  • 2018-10-22 Python31 原码、反码、补码

    原码、反码、补码 1)如何计算补码?规则: 正数:原码 = 反码 = 补码负数:反码 = 符号位不变,其他位取反补...

  • 原码、反码、补码以及位运算

    一、计算机在运算时都是以补码的形式进行的。1.非负数(即零和正数)的原码、反码、补码相同2.负数的反码:符号位不变...

  • 1.1 位运算基础

    Chapter1: 位运算的奇技淫巧 1. 位运算基础 1. 基本概念与基本运算 1.1 原码、反码与补码 在计算...

  • 数据的表示

    1位符号位+7位数值位正数:原码=反码=补码负数:反码=原码数值位取反 符号位不变补码=反码+1补码的表示范围位数...

  • 补码

    原码、反码、补码 原码:符号位 反码:减法变加法 补码:+1解决-0问题 数学原理 同余 反码:mod127 补码...

  • Java中的二进制相关运算

    正数的原码、反码、补码都是一样的负数第一位是1,表示负数,反码是在原码的基础上,符号位不动,其余取反;补码是反码+...

  • 原码、反码、补码

    规则: 计算机运算时,都是以补码的形式进行 正数的反码和补码都与原码相同。 负数的反码为对该数的原码除符号位外各位...

网友评论

    本文标题:Java基础——原码、反码、补码 以及 位运算

    本文链接:https://www.haomeiwen.com/subject/uedruftx.html