加入收藏 | 设为首页 | 会员中心 | 我要投稿 河北网 (https://www.hebeiwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

Java还在纠结原码、补码和反码?着实So Easy

发布时间:2019-07-17 13:32:22 所属栏目:建站 来源:BigDataKer 关注
导读:泛泛看jdk源码的时辰有很大的感伤,就是基本真的很重要,那什么是基本呢?除了java的根基语法之外,最基本的莫过于原码,反码和补码了以及根基的运算了! 1.原码、反码和补码 各人应该都知道,数据在计较机中是以二进制的情势存在的,好比 byte a = 6; byte
副问题[/!--empirenews.page--]

泛泛看jdk源码的时辰有很大的感伤,就是基本真的很重要,那什么是基本呢?除了java的根基语法之外,最基本的莫过于原码,反码和补码了以及根基的运算了!

Java还在纠结原码、补码和反码?着实So Easy

1.原码、反码和补码

各人应该都知道,数据在计较机中是以二进制的情势存在的,好比 byte a = 6; byte b = -6

分为两种环境来说,一种是正数,一种是负数;对付正数6来说,原码就是0000 0110,反码和补码也是这个;而对付-6来说,原码就是1000 0110,这是为什么呢?由于最高位(最左边的)是暗示标记,0暗示正数,1暗示负数;

不管是byte,short,int照旧其他的数字,最高位都是用来暗示标记的,以是-6的原码就是1000 0110,负数的反码就是标记稳固,其他的取反,就是1111 1001;负数的补码就是在反码的基本上加1就行了,因为是二进制的,是逢2进1,以是补码就是:1111 1010,;

留意:计较机中的加减运算(计较机中只有加法,可以通过加法暗示减法,就是用过补码的情势,看下面栗子)指的是补码之间的运算!并且负数在计较机中是以补码的情势存在并参加运算的,假如要变为十进制,就起首必要变为原码然后才气变为十进制或其他进制的数;

那么0怎么暗示呢?我们可以简朴看看:0 = 6-6 = 6+(-6)= [0000 0110]补+[1111 1010]补=[0000 0000]补=[0000 0000]原,那么有人要问了,补码1000 0000那又暗示几多呢?再看一个简朴的-1-127=(-1)

+(-127)= [1000 0001]原+[1111 1111]原 = [1111 1111]补+[1000 0001]补 = [1000 0000]补=[0000 0000]原,两个比拟一下,假如都行使原码的话统一个原码[0000 0000]原可以暗示两个数0和-128,而用补码的话却可以一个补码对应单独的一个数,很明明,一个补码对应一个数更切合我们的需求!!!

增补一下,对付负数来说,原码和反码之间彼此转化,试着领略着影象:

原码------>反码:标记位稳固,其他位取反 ;好比 [1000 0001]原 = [1111 1110]反

原码------>补码:标记位稳固,其他位取反,然后+1;好比 [1000 0001]原 = [1111 1111]补

反码------->原码:标记位稳固,其他位取反;好比 [1111 1110]反 = [1000 0001]原

反码------->补码:+1 ;好比 [1111 1110]反 = [1111 1111]补

补码------->原码:标记位稳固,其他位取反,然后+1;好比 [1111 1111]补 = [1000 0001]原

补码--------->反码:先变为原码,然后变反码;好比 [1111 1111]补 =[1111 1110]反

这些都是根基的对象,只要记着在计较机中运算的话,都是以补码的情势,并且这里就会涉及到一个进程,画一个简朴的图,计较机中运算都是用补码来举办的;而中间的转化进程计较机可以异常敏捷的转化,这个就不消我们劳神;下面我们就看看谁人运算到底包罗哪些运算。。。

JAVA还在纠结原码、补码和反码?着实So Easy

2.根基的运算

提及实际中的运算,无非就是四则运算,加减乘除,而对应于计较机中也有加减乘除,加减已经在上面说了,可以用补码的加法来实现加减,可是乘除呢?在这里我们就说说最简朴的乘除法啊,乘以2和除以2这种,假如是乘除其他数照旧较量伟大的,暂且我也没有什么乐趣研究,有乐趣的小搭档可以查查计较机中乘除法的实现,你会入神个中不行自拔!

以byte范例来举例,byte范例最高位是标记位,以是范畴是在1111 1111到01111 1111之间,酿成十进制也就是-127到127,加上0000 0000这个原码对应两个数0和-128,以是整个的范畴就是-128到127;

乘除也是分为两大块,正数和负数;

2.1 正数乘2运算(左移用<<暗示)

我们看看一个简朴的数(这里我正数也写一下补码):byte a = 5; 5的原码为:[0000 0101]原=[0000 0101]补 ;乘以2就便是10,原码为[0000 1010]原=[0000 1010]补

看看这两个补码有什么相关?就是将5的补码最右边添加一个0,最左边去掉一个0!最好是将5的补码看作一个整体,这个整体向左移动一位,左边高出的位数直接去掉,右边空的位置添0

JAVA还在纠结原码、补码和反码?着实So Easy

这个时辰会有一个题目,若是二进制补码是0100 0000,也就是64,向左移动一位,你认为是几多?谜底是-128,按理来说应该是正数的128啊,为什么是负的呢?记着,这个移位操纵是会包围标记位的,往左移动一位的补码是1000 0000,留意,这里万万不要酿成原码,在第一节中说过了补码为1000 0000的就是-128(这两个补码必然要留意点,很非凡,0000 0000代表十进制的0,1000 0000代表十进制的-128!万万不要酿成原码较量,由于他们的原码都是0000 0000无法区分)

public void num() { byte a = 64; byte b = (byte) (a<<1); System.out.println(b);//-128 }

2.2 正数除2运算(右移用>>暗示)

既然往左移动一位是乘以2,那么往右移动一位必定是除以2了!可是记着一个纪律,往右移动的话,右边超出来的部门去掉,左边空出来的位置添加和标记位沟通的数!(记着了纪律这个负数的右移一样的)

举个例子,65的补码0100 0001,向右移动一位,补码应该是0010 0000,记着,此时最左边的0是按照标记位是0才添加的0,是正数,右移后的原码和补码一样,那么酿成十进制应该是32,这里可以看出一个大于0的奇数右移一位的功效就是除以2然后向下取整,偶数的话直接就是除以2了

  1. public void num() { 
  2.  byte a = 64; 
  3.  byte b = (byte) (a<<1); 
  4.  System.out.println(b);//-128 
  5.   
  6.  } 

2.3 负数乘2运算(<<)

正数着实较量轻易,可是负数的话就轻微贫困一点!譬喻-127的补码是1000 0001,左移一位的补码0000 0010,因为这个补码是正的,以是原码也是这个,酿成十进制就是2,有没有认为出格故意思,哈哈哈!知道为什么吗?由于byte的范畴是-128到127啊,只要是高出了这个范畴的就会酿成你想不到的数!

再举个没有高出范畴的例子,-6的补码是1111 1010,左移一位的补码就是1111 0100,因为是负的,酿成原码为1000 1100,也就是对应十进制的-12,这个功效和想象的一样!

2.4 负数除2运算(>>)

(编辑:河北网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读