java中负数表示方法:(绝对值取反码再加一)
计算机对有符号数(包括浮点数)的表示有三种方法:原码、反码和补码,补码=反码+1。在 二进制里,是用 0 和 1 来表示正负的,最高位为符号位,最高位为 1 代表负数,最高位为0 代表正数。
以java中8位的byte为例,最大值为:01111111,最小值为1000 0000。
那么根据十进制的数字,我们如何转换为二进制呢?对于正数我们直接转换即可,对于负数则有一个过程。
以负数-5为例:
1.先将-5的绝对值转换成二进制,即为00000101;
2.然后求该二进制的反码,即为1111 1010;
3.最后将反码加1,即为:1111 1011
所以Java中Integer.toBinaryString(-5)结果为11111111 11111111 1111111111111011. Integer是32位(bit)的.
右移:(正数左补0、负数左补1)
System.out.println(-3>>1);
结果是-2,为什么会是-2呢?下面我们来看一下.
System.out.println(Integer.toHexString(-3));得到-3的16进制为fffffffd(此为-3的补码,计算机中负数用补码表示).
转换成2进制为1111 1111 1111 1111 1111 1111 1111 1101
右移一位为1111 1111 1111 1111 1111 1111 1111 1110,显而易见此为-2补码.
左移(正负数皆右补0)
System.out.println(-3<<1);左移相对来说比较简单.
1111 1111 1111 1111 1111 1111 1111 1101左移一位为
1111 1111 1111 1111 1111 1111 1111 1010,其为-6的补码.
System.out.println(Integer.MAX_VALUE<< 1);输出为-2
无符号右移(正数左补0负数左补1)
System.out.println(-3>>>1);
1111 1111 1111 1111 1111 1111 1111 1101无符号右移,高位补0,
01111 1111 1111 1111 1111 1111 1111 1110,其为2147483646的原码.
为什么没有无符号左移?
因为左移是在后面补0
而右移是在前面边补1或0
有无符号是取决于数的前面的第一位是0还是1
所以右移是会产生到底补1还是0的问题。
而左移始终是在右边补,不会产生符号问题。
所以没有必要无符号左移<<<。
无符号左移<<<和左移<<是一样的概念
附:
1.java中表示二进制、八进制、十进制、十六进制
java里不能这样表示二进制,只能是 8,10,16进制
8: 前置 0
10: 不需前置
16: 前置 0x或者0X
2.为
计算机对带符号数的表示有三种方法:原码、反码和补码
10000000-11111111表示-128到-1,
补码的1111 1111转换成原码就是1000 0001,也就是-1。
补码就是二进制表示负数的一种方法
引入了补码概念. 负数的补码就是对反码加一,而正数不变,正数的原码反码补码是一样的.在补码中用(-128)代替了(-0),所以补码的表示范围为:
(-128~0~127)共256个.
注意:(-128)没有相对应的原码和反码, (-128) = (10000000)
为了充分利用资源,就将原来本应该表示“-0”的补码规定为代表-128
所谓原码就是二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。
反码表示法规定:正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。
补码表示法规定:正数的补码与其原码相同;负数的补码是在其反码的末位加1。