计算机基础--java中<< >> >>>的区别用法
2016-01-11 13:26
323 查看
首先谈之前需要明白一下几点:
1 对于数字 在计算机中存贮和计算都是以补码的形式 正数的补码和反码就是它本身 负数的补码是反码+1 注意对于有符号的数字 最高位表示符号位 0表示正 1表示负
2 之所以用补码进行计算和存储的原因:
1)使符号位能与有效值部分一起参加运算,从而简化运算规则。从而可以简化运算器的结构,提高运算速度;(减法运算可以用加法运算表示出来。)
2)加法运算比减法运算更易于实现。使减法运算转换为加法运算,进一步简化计算机中运算器的线路设计。【从补码运算的特征理解!】
3)为了防止0的机器数有两个编码。
注意:
-128 --- -1 或10000000 - 11111111
0 ---- 127 或00000000 - 01111111
注意:0的机器码只有唯一的一种表示(编码),即00000000;没有-0这种说法,10000000不是-1的编码,而是-128的编码 ;另外10000000没有补码和反码
详情参考:http://blog.sina.com.cn/s/blog_9e67285801010vms.html
http://www.360doc.com/content/12/1009/21/10086564_240513741.shtml
3因此 << >> >>>都是对补码进行操作 此点重要 byte 和 char在进行移位操作时候 都是转换为int进行操作
一:<<表示左移运算
左移的规则只记住一点:丢弃最高位,0补最低位
如果移动的位数超过了该类型的最大位数,那么编译器会对移动的位数取模。如对int型移动33位,实际上只移动了1位
举例正数:4
补码:0000 0000 0000 0000 0000 0000 0000 0100(正数补码=原码)
4<<1
=8 0000 0000 0000 0000 0000 0000 0000 1000 此时虽然丢弃了最高位 但是左移后符号并没有改变 仍然为正
---------------------------------------------------------------------
举例负数:-4
补码:11111111111111111111111111111100
-4<<1
= -8 11111111111111111111111111111000 (再取反+1就还原为原码) 此时虽然丢弃了最高位1 但是左移后符号并没有改变 仍然为负
二 >>有符号右移
右移的规则只记住一点:符号位(正负)不变,左边补上符号位(正数左边补0 负数左边补1 有差别 因此叫做有符号右移)
举例正数:4
补码:0000 0000 0000 0000 0000 0000 0000 0100(正数补码=原码)
4>>1
=2 0|000 0000 0000 0000 0000 0000 0000 0010 符号位置正负不变 |左边补0
---------------------------------------------------------------------
举例负数:-4
补码:11111111111111111111111111111100
-4>>1
= -2 1|1111111111111111111111111111000 (再取反+1就还原为原码) 符号位置不变 |左边补上1
三 >>>无符号右移
无符号右移的规则只记住一点:忽略了符号位扩展,0补最高位 (那么此时负数的话会带来正负号变化的问题)
举例正数:4
补码:0000 0000 0000 0000 0000 0000 0000 0100(正数补码=原码)
4>>>1
=2 0000 0000 0000 0000 0000 0000 0000 0010 忽略符号位 直接在符号位左边补0
---------------------------------------------------------------------
举例负数:-4
补码:11111111111111111111111111111100
-4>>>1
= 2147483646 (由负变正 此时为正数 补码以0开头 正数的原码 补码相等 此时补码就是原码)
01111111111111111111111111111110 忽略符号位 直接在符号位左边补0
到这了那么会产生问题,无符号右移为什么这么奇怪? 有什么意义吗?
无符号右移在数据变换时非常重要。
比如对byte b;做无符号右移,在众多散列、加密、压缩、影音媒体编码、序列化格式都会用到。如果没有这个无符号右移,就需要用更大的空间去做有符号右移。
比如byte就需哟short,short就需要int去做,浪费空间和时间。总之,无符号右移的应用场合大大多于有符号右移。(欢迎补充指正)
此处参考:http://www.zybang.com/question/3666fc8d9c9903e808803ca8781670a2.html
四:为什么没有<<<
从上面可以看出,左移是在右边补0 不管正数负数 右边补0 都对符号位不产生影响 不产生符号问题
右移是在左边补,正数补0 负数补1(都是对补码而言)
因此没必要无符号左移 <<<和<<是一样的概念
1 对于数字 在计算机中存贮和计算都是以补码的形式 正数的补码和反码就是它本身 负数的补码是反码+1 注意对于有符号的数字 最高位表示符号位 0表示正 1表示负
2 之所以用补码进行计算和存储的原因:
1)使符号位能与有效值部分一起参加运算,从而简化运算规则。从而可以简化运算器的结构,提高运算速度;(减法运算可以用加法运算表示出来。)
2)加法运算比减法运算更易于实现。使减法运算转换为加法运算,进一步简化计算机中运算器的线路设计。【从补码运算的特征理解!】
3)为了防止0的机器数有两个编码。
注意:
-128 --- -1 或10000000 - 11111111
0 ---- 127 或00000000 - 01111111
注意:0的机器码只有唯一的一种表示(编码),即00000000;没有-0这种说法,10000000不是-1的编码,而是-128的编码 ;另外10000000没有补码和反码
详情参考:http://blog.sina.com.cn/s/blog_9e67285801010vms.html
http://www.360doc.com/content/12/1009/21/10086564_240513741.shtml
3因此 << >> >>>都是对补码进行操作 此点重要 byte 和 char在进行移位操作时候 都是转换为int进行操作
一:<<表示左移运算
左移的规则只记住一点:丢弃最高位,0补最低位
如果移动的位数超过了该类型的最大位数,那么编译器会对移动的位数取模。如对int型移动33位,实际上只移动了1位
举例正数:4
补码:0000 0000 0000 0000 0000 0000 0000 0100(正数补码=原码)
4<<1
=8 0000 0000 0000 0000 0000 0000 0000 1000 此时虽然丢弃了最高位 但是左移后符号并没有改变 仍然为正
---------------------------------------------------------------------
举例负数:-4
补码:11111111111111111111111111111100
-4<<1
= -8 11111111111111111111111111111000 (再取反+1就还原为原码) 此时虽然丢弃了最高位1 但是左移后符号并没有改变 仍然为负
二 >>有符号右移
右移的规则只记住一点:符号位(正负)不变,左边补上符号位(正数左边补0 负数左边补1 有差别 因此叫做有符号右移)
举例正数:4
补码:0000 0000 0000 0000 0000 0000 0000 0100(正数补码=原码)
4>>1
=2 0|000 0000 0000 0000 0000 0000 0000 0010 符号位置正负不变 |左边补0
---------------------------------------------------------------------
举例负数:-4
补码:11111111111111111111111111111100
-4>>1
= -2 1|1111111111111111111111111111000 (再取反+1就还原为原码) 符号位置不变 |左边补上1
三 >>>无符号右移
无符号右移的规则只记住一点:忽略了符号位扩展,0补最高位 (那么此时负数的话会带来正负号变化的问题)
举例正数:4
补码:0000 0000 0000 0000 0000 0000 0000 0100(正数补码=原码)
4>>>1
=2 0000 0000 0000 0000 0000 0000 0000 0010 忽略符号位 直接在符号位左边补0
---------------------------------------------------------------------
举例负数:-4
补码:11111111111111111111111111111100
-4>>>1
= 2147483646 (由负变正 此时为正数 补码以0开头 正数的原码 补码相等 此时补码就是原码)
01111111111111111111111111111110 忽略符号位 直接在符号位左边补0
到这了那么会产生问题,无符号右移为什么这么奇怪? 有什么意义吗?
无符号右移在数据变换时非常重要。
比如对byte b;做无符号右移,在众多散列、加密、压缩、影音媒体编码、序列化格式都会用到。如果没有这个无符号右移,就需要用更大的空间去做有符号右移。
比如byte就需哟short,short就需要int去做,浪费空间和时间。总之,无符号右移的应用场合大大多于有符号右移。(欢迎补充指正)
此处参考:http://www.zybang.com/question/3666fc8d9c9903e808803ca8781670a2.html
四:为什么没有<<<
从上面可以看出,左移是在右边补0 不管正数负数 右边补0 都对符号位不产生影响 不产生符号问题
右移是在左边补,正数补0 负数补1(都是对补码而言)
因此没必要无符号左移 <<<和<<是一样的概念
相关文章推荐
- BF算法
- Linux内核工程导论——网络:Filter(LSF、BPF、eBPF)
- [计算机网络] vsftpd的安装与使用
- 从僵尸网络追踪到入侵检测 第4章 Honeyd动态模板防御扫描软件攻击二
- 【网络基础】路由表,分组转发算法
- 网络监控系统
- IOS-底层数据结构
- PHP的异步并行网络扩展swoole
- Haffman编码/译码——数据结构作业(二)
- iOS 中client和server的 Web Service 网络通信 (2)
- 浏览器与HTTP网络协议缓存原理分析
- 校园导航——数据结构作业(一)
- 1.5.3 HTTP HEADERS
- (转) 一次批量重启引发的Neutron网络故障
- HTTPUrlConnection 出现 FileNotFoundException 的问题
- http详解
- linux网络设备—mdio总线
- Android网络请求框架:Volley简单使用
- linux抓包命令-tcpdump命令详解
- 有孚网络获评上海十佳IDC、优秀企业邮箱服务商