转换:

Java整型数据类型有:byte、char、short、int、long。要把它们转换成二进制的原码形式,必须明白他们各占几个字节。,一个字节==8位数

数据类型                           所占位数
      byte                                       8 
      boolean                                8
      short                                    16
      int                                         32 
      long                                      64 
      float                                      32 
      double                                  64 
      char                                     16

byte
正数最大位0111 1111,也就是数字127 
负数最大为1111 1111,也就是数字-128
反码与补码
1、反码:
        一个数如果是正,则它的反码与原码相同;
        一个数如果是负,则符号位为1,其余各位是对原码取反;

2、补码:利用溢出,我们可以将减法变成加法
       对于十进制数,从9得到5可用减法:
       9-4=5    因为4+6=10,我们可以将6作为4的补数
       改写为加法:
       9+6=15(去掉高位1,也就是减10)得到5.

对于十六进制数,从c到5可用减法:
       c-7=5    因为7+9=16 将9作为7的补数
       改写为加法:
       c+9=15(去掉高位1,也就是减16)得到5.

在计算机中,如果我们用1个字节表示一个数,一个字节有8位,超过8位就进1,在内存中情况为(100000000),进位1被丢弃。

⑴一个数为正,则它的原码、反码、补码相同
    ⑵一个数为负,刚符号位为1,其余各位是对原码取反,然后整个数加1
     详细请参考http://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html
Integer.toHexString的参数是int,如果不进行&0xff,那么当一个byte会转换成int时,由于int是32位,而byte只有8位这时会进行补位,
例如补码11111111的十进制数为-1转换为int时变为11111111111111111111111111111111好多1啊,即0xffffffff但是这个数是不对的,这种补位就会造成误差。
和0xff相与后,高24比特就会被清0了,结果就对了。

还需要明白一点的是:计算机表示数字正负不是用+ -加减号来表示,而是用最高位数字来表示,0表示正,1表示负

在计算机系统中,数值一律用补码来表示(存储)。
主要原因:使用补码,可以将符号位和其它位统一处理;同时,减法也可按加法来处理。另外,两个用补
码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃。
补码与原码的转换过程几乎是相同的。
数值的补码表示也分两种情况:
(1)正数的补码:与原码相同。
      例如,+9的补码是00001001。
(2)负数的补码:符号位(最高位)为1,其余位为该数绝对值的原码按位取反;然后整个数加1。
      例如,-7的补码:因为是负数,则符号位为“1”,整个为10000111;其余7位为-7的绝对值+7的原码
     0000111按位取反为1111000;再加1,所以-7的补码是11111001。
已知一个数的补码,求原码的操作分两种情况:
(1)如果补码的符号位为“0”,表示是一个正数,所以补码就是该数的原码。
(2)如果补码的符号位为“1”,表示是一个负数,求原码的操作可以是:符号位为1,其余各位取反,然后再整个数加1。
     例如,已知一个补码为11111001,则原码是10000111(-7):因为符号位为“1”,表示是一个负数,所以该位不变,仍为“1”;其余7位1111001取反后为0000110;再加1,所以是10000111。

源码:是什么就是什么。负数就是最前面符号位为1。
反码:正的就是补码,负的就是各位取反,0换1,1换0,注意,最高位符号为不变。
补码:正的就是源码,负的就是反码+1
比如: -1 -2
以8位二进制为例
源码:10000001 10000010
反码:11111110 11111101
补码:11111111 11111110
补码这样做的好处是什么呢?
请看-1+(-2)电脑怎么做:
用源码:10000001 + (10000010)=00000011 这是什么?是-3吗?不是,是3。所以不能直接用源码做加法。
用反码:11111110 + (11111101)=11111011 这是什么?是反码的"-4"
用补码:11111111 + (11111110)=11111101 末尾减一再取反得10000011,所以结果是补码的-3。
反码为什么出错?以4位数为例,高位为符号位(括号内为绝对值):
1010 (2)取反 1101 (5)
1011 (3)取反 1100 (4)
然后 -2 + (-3) 变成了 -(5 + 4)超出8的部分舍去,得 1001,再取反得 1110,成了-6
究其原因:各位取反的两数相加:1010+0101=1111必是全1即绝对值为7,2->5,3->4,相对于8共偏差了2,然后9=1mod8,1->6,只修正了1点偏差,
结果就出现了1的偏差。补码中末尾加一就是修正了该偏差,得到正确的结果。即2->6,3->5.相对于8无偏差11=3mod8,3->5。

位运算符:

位移进制运算

带符号右移 题:-15 >> 2 = -4

15原码:   00000000 00000000 00000000 00001111 //32位,二进制
反码:    11111111 11111111 11111111 11110000 //0变1,1变0
补码:    11111111 11111111 11111111 11110001 //最后位加1,-15二进制
右移2位:  11111111 11111111 11111111 11111100 //右边丢弃2位,前面30位保留,左边补1
取反:      00000000 00000000 00000000 00000011 //0变1,1变0
+1:                                       3+1
结果:                                     =-4 //负号保留,十进制

带符号左移 题: 10 << 2 = 40
10 补码:    00000000 00000000 00000000 00001010 //32位,二进制
左移2位:    00000000 00000000 00000000 00101000 //左边丢弃2位,右边补0
结果:                                       
40 //十进制
 

无符号右移 题:-4321 >>> 30 = 3
4321原码:         00000000
00000000 00010000 11100011 //32位,二进制
反码:           11111111 11111111 11101111 00011100 //0变1,1变0
补码:           11111111 11111111 11101111 00011101 //最后位加1,-4321二进制
无符号右移30位:  00000000 00000000 00000000 00000011 //右边丢弃30位,前面二位保留,左边补0
结果:                                                3 //十进制

& 位逻辑与 题:44 & 21 = 4
44 补码:    00000000 00000000 00000000 00101100 //32位,二进制
21 补码:    00000000 00000000 00000000 00010101 //32位,二进制
& 运算:     00000000 00000000 00000000 00000100 //对应的两个二进制位均为1时 结果位才为1 否则为0
结果:                                         4 //十进制   
                               
| 位逻辑与 题:9 | 5 = 13
9 补码:    00000000 00000000 00000000 00001001 //32位,二进制
5 补码:    00000000 00000000 00000000 00000101 //32位,二进制
| 运算:    00000000 00000000 00000000 00001101 //对应的二个二进制位有一个为1时,结果位就为1
结果:                                       13 //十进制

^ 位逻辑异或 题: 9 ^ 5 = 12
9 补码:    00000000 00000000 00000000 00001001 //32位,二进制
5 补码:    00000000 00000000 00000000 00000101 //32位,二进制
| 运算:    00000000 00000000 00000000 00001100 //对应的二进制位相异时,结果为1
结果:                                       12 //十进制

~ 位逻辑反 题: ~9 = -10
9 补码:    00000000 00000000 00000000 00001001 //32位,二进制
~ 运算:    11111111 11111111 11111111 11110110 //最高位为1表示为一个负数,则进行取反加1
取反:      00000000 00000000 00000000 00001001 //32位,二进制
+1:                                      9+1 //32位,二进制
结果:                                      -10 //十进制

由于数据类型所占字节是有限的,而位移的大小却可以任意大小,所以可能存在位移后超过了该数据类型的表示范围,于是有了这样的规定: 如果为int数据类型,且位移位数大于32位,则首先把位移位数对32取模,不然位移超过总位数没意义的。所以4>>32与4>>0是等价的。

如果为long类型,且位移位数大于64位,则首先把位移位数对64取模,若没超过64位则不用对位数取模。

如果为byte、char、short,则会首先将他们扩充到32位,然后的规则就按照int类型来处理。

实际应用:


1.  判断int型变量a是奇数还是偶数    
     a&1  = 0 偶数 
     a&1 =  1 奇数 
2.  求平均值,比如有两个int类型变量x、y,首先要求x+y的和,再除以2,但是有可能x+y的结果会超过int的最大表示范围,所以位运算就派上用场啦。
      (x&y)+((x^y)>>1); 
3.  对于一个大于0的整数,判断它是不是2的几次方
    ((x&(x-1))==0)&&(x!=0); 
4.  比如有两个int类型变量x、y,要求两者数字交换,位运算的实现方法:性能绝对高效
    x ^= y; 
    y ^= x; 
    x ^= y; 
5. 求绝对值
    int abs( int x ) 
   { 
     int y ; 
     y = x >> 31 ; 
    return (x^y)-y ;        //or: (x+y)^y 
   }
6.  取模运算,采用位运算实现:
     a % (2^n) 等价于 a & (2^n - 1) 
7.  乘法运算   采用位运算实现
     a * (2^n) 等价于 a << n
8.   除法运算转化成位运算
      a / (2^n) 等价于 a>> n 
9.   求相反数
      (~x+1) 
10  a % 2 等价于 a & 1 

Java的位运算符与二进制转换的更多相关文章

  1. Java基础-位运算符Bitwise Operators

    Java基础-位运算符Bitwise Operators 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.位运算特点 位运算符分为按位与(&),按位或(|),按位异或(^ ...

  2. Java的位运算符实例——与(&)、非(~)、或(|)、异或(^)

    一.Java的位运算符实例——与(&).非(~).或(|).异或(^) 1.与(&) 0 & 2 = 0 0 0 0 0 1 0 0 1 0 2.非(~) ~0 = 7 0 0 ...

  3. JAVA 十六进制和十进制、二进制转换

    java十六进制和十进制.二进制转换 十进制转化成十六进制 Integer x = 100; hex = x.toHexString(x); 十六进制转化成十进制 Integer.parseInt(h ...

  4. Java的位运算符详解实例——与(&)、非(~)、或(|)、异或(^)

    位运算符主要针对二进制,它包括了:“与”.“非”.“或”.“异或”.从表面上看似乎有点像逻辑运算符,但逻辑运算符是针对两个关系运算符来进行逻辑运算,而位运算符主要针对两个二进制数的位进行逻辑运算.下面 ...

  5. Java的位运算符—— 与(&)、非(~)、或(|)、异或(^)

    位运算符主要针对二进制,它包括了:“与”.“非”.“或”.“异或”.从表面上看似乎有点像逻辑运算符,但逻辑运算符是针对两个关系运算符来进行逻辑运算,而位运算符主要针对两个二进制数的位进行逻辑运算.下面 ...

  6. Java的位运算符具体解释实例——与(&amp;)、非(~)、或(|)、异或(^)

    位运算符主要针对二进制,它包含了:“与”.“非”.“或”.“异或”.从表面上看似乎有点像逻辑运算符,但逻辑运算符是针对两个关系运算符来进行逻辑运算,而位运算符主要针对两个二进制数的位进行逻辑运算.以下 ...

  7. Java中位运算符的使用

    先预知识: 数据在计算机中是以二进制的形式进行存储的,而二进制在内存中是以补码的形式进行存储的.在介绍位运算之前,首先来看一下原码.反码和补码的概念.由于正数的原码.反码和补码的形式都是一样的,所以以 ...

  8. Java的位运算符—与(&)、非(~)、或(|)、异或(^)

    位运算符主要针对二进制,它包括了:“与”.“非”.“或”.“异或”.从表面上看似乎有点像逻辑运算符,但逻辑运算符是针对两个关系运算符来进行逻辑运算,而位运算符主要针对两个二进制数的位进行逻辑运算.下面 ...

  9. 恶补java基础 位运算符

    以前不知道在哪看过别人写博客里的一句话  “越学的深入觉得自己会的东西越少”.最近研究了一下java的基础算法  hash表 被一些位运算符搞的头都大了 决心花一些时间研究一下以前一直觉得没用的东西! ...

随机推荐

  1. 【题解】ZJOI2010贪吃的老鼠

    %%%%真的好强...看题解我都看了好久才完全明白.放一下参考的博客,谢谢神犇QAQ 1号博客    2号博客(超级赞的啦) 因为理解的过程太艰辛,所以必须记录一下这道强题:这道题目最难的两个约束就在 ...

  2. GYM - 100814 C.Connecting Graph

    题意: 初始有n个点,m次操作.每次操作加一条边或者询问两个点第一次连通的时刻(若不连通输出-1). 题解: 用并查集维护每个点所在连通块的根.对于每次加边,暴力的更新新的根. 每次将2个块合并时,将 ...

  3. 【MySQL】数据库 --MySQL的安装

    本篇教程主要讲解在CentOS 6.5下编译安装MySQL 5.6.14! 1.卸载旧版本: 使用下面的命令检测是否安装有MySQL server <span style="font- ...

  4. 构建一个类jq的函数库

    jqfree core var $ = function(selector, context) { return new $.fn.init(selector, context); }; $.fn = ...

  5. webpack 的第三方库分离并持久化缓存

    我们常常需要在浏览器缓存一些稳定的资源,如第三方库等.要达到这个目标,只需要两步: 1.提取出“稳定的资源”: 2.提供稳定的文件hash . 处理后的出的文件就像这样子: app.1w3ad4q4. ...

  6. 用eval转化对象

    var str = '{"name": "tom","age": 12,"sex": "man"}' ...

  7. NET中IL理解(转)

    .NET CLR 和 Java VM 都是堆叠式虚拟机器(Stack-Based VM),也就是說,它們的指令集(Instruction Set)都是採用堆叠运算的方式:执行时的资料都是先放在堆叠中, ...

  8. [洛谷P1528] 切蛋糕

    洛谷题目链接:切蛋糕 题目描述 Facer今天买了n块蛋糕,不料被信息组中球球等好吃懒做的家伙发现了,没办法,只好浪费一点来填他们的嘴巴.他答应给每个人留一口,然后量了量每个人口的大小.Facer有把 ...

  9. BZOJ 4514: [Sdoi2016]数字配对

    4514: [Sdoi2016]数字配对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1606  Solved: 608[Submit][Statu ...

  10. go语言实现拷贝文件

    package main import ( "fmt" "io" "os" ) func main(){ list := os.Args / ...