1.为什么要使用二进制?
首先我们需要知道:
计算机底层的存储方式:所有数字在计算机底层都以二进制形式存在。
二进制数据的存储方式:所有的数值,不管正负,底层都以补码的方式存储。
二进制是机器语言,由于计算机并不能像人一样计算与思考,而使用二进制,仅用0、1来表示,0和1分别表示高低电频,使计算机处理起来更方便也更加高效。
2.关于原码,反码,补码,以及之间的转换:
十进制中的正数转换为二进制后原码,反码,补码都相同。 以下讨论为负数时的情况:
原码:直接将一个数值转换为二进制,最高位是符号位。符号位正数为0,负数为1。
反码:除符号位,对原码进行按位取反。
补码:该数值的反码+1。
eg:数值:-14
原码: 10000000 00000000 00000000 00001110
反码: 11111111 11111111 11111111 11110001 除符号位按位取反
补码: 11111111 11111111 11111111 11110010 反码基础上加一
我们已经知道了原码-->反码-->补码 的转换。
接下来了解从补码转换成原码:
方法一:逆运算法:补码先进行减一操作,除符号位再按位取反。
方法二:对补码直接进行再补码,得到的是原码。
数值:-14
补码: 11111111 11111111 11111111 11110010
方法一:
减一: 11111111 11111111 11111111 11110001
取反: 10000000 00000000 00000000 00001110 =-14
方法二:
取反: 10000000 00000000 00000000 00001101
加一: 10000000 00000000 00000000 00001110 =-14
十进制转换为二进制的转换:
方法:除二取余的逆
eg:数值:13
13 余数
/2 6 1
/2 3 0
/2 1 1
/2 0 1
取余的逆:1101
3.为什么要使用原码、反码、补码?
首先我们知道了计算机底层是通过二进制进行存储的,并且存储的方式也是补码形式存在的,那么我们先通过计算机的一种方式来进行思考,因为只有 0、1 两种信号方式,那么在进行运算时,加减乘除已经是最基本的运算,并且由于第一位是符号位,计算机不能像人脑一样识别并对之后的值进行运算,那么在设计计算机的时候就应该对计算方式尽量简化,以达到高效识别并运算于是我们通过反码,补码的形式,让符号位也参与运算。目的:让计算机运算更加简便,而且让符号位也参加运算
首先,在我们的数学中,2-1=2+(-1)。那么如果通过这种思想,我们可以让计算机只有加法,那么会简便很多,并且会简化计算机的冗余。
3.1为什么不使用原码计算?
eg: 2+(-1)
如果通过原码计算:
00000000 00000000 00000000 00000010 2
+10000000 00000000 00000000 00000001 +-1
=10000000 00000000 00000000 00000011 =-3
如果通过反码计算:
00000000 00000000 00000000 00000010 2
+11111111 11111111 11111111 11111110 +-1 (在计算时,高位溢出后在低位上补)
=00000000 00000000 00000000 00000001 = 1
如果通过补码计算:
00000000 00000000 00000000 00000010 2
+11111111 11111111 11111111 11111111 +-1 (在计算时,高位溢出后就忽略不计)
=00000000 00000000 00000000 00000001 = 1
首先通过原码计算已经得出,在有负数的情况下,结果是不对的,所以不采用原码。
那么,反码和补码结果都对时,为什么不使用反码呢?
下面我们来看一个例子:
eg:1+(-1)
使用反码计算:
00000000 00000000 00000000 00000001 (反码) 1
+11111111 11111111 11111111 11111110 (反码) +-1
=11111111 11111111 11111111 11111111 (反码)
=10000000 00000000 00000000 00000000 (原码) =-0
从例子中可以看出,1+(-1)=-0 ,而我们的常识中0是偶数,是不分正负的。
于是问题出现:两个编码同时表示0。[10000000 00000000 00000000 00000000] 与[00000000 00000000 00000000 00000000]
那么我们再来看补码:
eg:1+(-1)
使用补码进行计算:
00000000 00000000 00000000 00000001 (1的补码)
+11111111 11111111 11111111 11111111 (-1的补码)
=00000000 00000000 00000000 00000000 =0
于是通过补码我们找到更好的解决方式来解决编码问题,解决了两个编码表示零的问题,并且我们把在反码中的-0用来表示最低数,例如,byte中用[10000000]表示-128,用[00000000]表示0。最终:通过补码, 我们修复了由于0而存在的符号问题以及存在两个编码的问题, 并把-0用来表示一个最低数。
4.解惑:byte的取值范围为什么是 -128~127.
首先byte是由8位二进制来表示:
那么2^8=256,但是我们不仅要表示正数还要表示负数,那么为什么是-128~127呢?
因为我们需要一半用来表示正数,一半用来表示负数。那么,第一位叫符号位,之后的都是真值,最大为01111111=127. 而11111111表示的是-127。用000000000表示0,用10000000表示-128(此时-128是没有原码和补码的)。
11111111转为二进制是-127(第一位是符号位),-128又是如何表示的呢?
解答:
首先第一位是符号位,不进行表示数值,那么仅有后七位来进行表示数值,但是通过补码的使用,解决了。
如果觉得我解释的不够清楚,推荐看这一篇:计算机底层基础----原码、反码、补码以及为什么要用反码和补码_libraryhu的专栏-CSDN博客
如果觉得这篇文章有帮到你,希望能给个小小的赞,谢谢。