数值在计算机中是以补码的方式存储的。
一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1。比如,十进制中的数 +2 ,计算机字长为8位,转换成二进制就是[00000010]。如果是 -2 ,就是 [10000010] 。因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数 [10000010],其最高位1代表负,其真正数值是 -2 而不是形式值130([10000010]转换成十进制等于130)。所以将带符号位的机器数对应的真正数值称为机器数的真值。
原码:所谓原码就是二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。
反码:正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。
补码:正数的补码与其原码相同;负数的补码是在其反码的末位加1。
示例:
+100表示为2进制数为+1100100
原码=01100100 反码=01100100 补码=01100100 正数的话3码都一样
-100表示为2进制树为-1100100
原码=11100100 反码=10011011(第一位表示符号的数字不变)
补码=反码+1=10011100
原码=01100100 反码=01100100 补码=01100100 正数的话3码都一样
-100表示为2进制树为-1100100
原码=11100100 反码=10011011(第一位表示符号的数字不变)
补码=反码+1=10011100
计算机为什么要使用补码呢?
首先,根据运算法则减去一个正数等于加上一个负数, 即: 1-1 = 1+(-1), 所以计算机被设计成只有加法而没有减法, 而让计算机辨别”符号位”会让计算机的基础电路设计变得十分复杂,于是就让符号位也参与运算,从而产生了反码。
用反码计算, 出现了”0”这个特殊的数值, 0带符号是没有任何意义的。 而且会有[0000 0000]和[1000 0000]两个编码表示0。于是设计了补码, 负数的补码就是反码+1,正数的补码就是正数本身,从而解决了0的符号以及两个编码的问题: 用[0000 0000]表示0,用[1000 0000]表示-128。
注意-128实际上是使用以前的-0的补码来表示的, 所以-128并没有原码和反码。使用补码, 不仅仅修复了0的符号以及存在两个编码的问题, 而且还能够多表示一个最低数。 这就是为什么8位二进制, 使用补码表示的范围为[-128, 127]。
用反码计算, 出现了”0”这个特殊的数值, 0带符号是没有任何意义的。 而且会有[0000 0000]和[1000 0000]两个编码表示0。于是设计了补码, 负数的补码就是反码+1,正数的补码就是正数本身,从而解决了0的符号以及两个编码的问题: 用[0000 0000]表示0,用[1000 0000]表示-128。
注意-128实际上是使用以前的-0的补码来表示的, 所以-128并没有原码和反码。使用补码, 不仅仅修复了0的符号以及存在两个编码的问题, 而且还能够多表示一个最低数。 这就是为什么8位二进制, 使用补码表示的范围为[-128, 127]。
位运算
与运算符&
示例:
package 练习一;
public class Shu {
public static void main(String[] args) {
System.out.println(2&3);
System.out.println(2&3);
}
}
运行结果:
2
分析:
只有两个都是1时,结果才为1
2:00000010
3:00000011
2&3:00000010 即为2
或运算符|
示例:
package 练习一;
public class Shu {
public static void main(String[] args) {
System.out.println(2|3);
System.out.println(2|3);
}
}
运行结果:
3
分析:
两个位只要有一个为1,那么结果就是1,否则就为0,
2:00000010
3:00000011
2&3:00000011 即为3
非运算符~
示例:
package 练习一;
public class Shu {
public static void main(String[] args) {
System.out.println(~2);
}
}
public static void main(String[] args) {
System.out.println(~2);
}
}
运算结果:
-3
如果位为0,结果是1,如果位为1,结果是0,
异或运算^
package 练习一;
public class Shu {
public static void main(String[] args) {
System.out.println(2^3);
}
}
public static void main(String[] args) {
System.out.println(2^3);
}
}
结果:1
分析:两个操作数的位中,相同则结果为0,不同则结果为1。
2:00000010
3:00000011
2&3:00000001 即为1