文档章节

关于原码&反码&补码&移位运算详解

天堂之镜
 天堂之镜
发布于 2015/02/12 21:47
字数 954
阅读 70
收藏 0

 移位运算详解


 
下面是负-2的补码,也是负数的内存中实际存储的形式。
 11111111111111111111111111111110
下面是-2的反码:
 11111111111111111111111111111101
下面是正2的原码:
 前面省略30个0:……10
 
##################
2的编码(原码)
 00000000000000000000000000000010
2右移1位后的原码(相当于除2)
 00000000000000000000000000000001
 
2的编码(原码)
 00000000000000000000000000000010
2无符号右移1位后的原码(相当于除2)
 00000000000000000000000000000001

################
负数有符号右移的步骤
-3的编码(补码):
 11111111111111111111111111111101
-3右移1位后的补码(有符号,负数补1,正数补0)
 11111111111111111111111111111110
 
-3的编码(补码):
 11111111111111111111111111111101
-3无符号右移1位后的补码(无符号都补0)
 01111111111111111111111111111110
 
########################
正数(-a)的编码(原码)
 01111110000000110000000000000000
负数a的编码(补码)
 10000001111111010000000000000000
负数a无符号右移(为正)后的编码(补码-并直接补0)
 01000000111111101000000000000000
 
负数a的编码(补码)
 10000001111111010000000000000000
负数a右移(仍然为负)的编码(补码)
 11000000111111101000000000000000
 
负数a的编码(补)
 10000001111111010000000000000000
负数a左移1位后(仍为负)的编码(补)
 00000011111110100000000000000000
 
 
 
总结:
 正数在内存中只有一种存在形式:原码。
 负数在内存中也只有一种存在形式:补码。
 只是人们发现,负数的编码可以由正数的编码(原)取反(反)再加1得到。
 正数的编码可以由负数的编码(补)减1(反)再取反(原)得到

 对于无符号右移,直接将正数(原)或负数(补)的编码从第一到第三十二依次右移,再在最最前端补0.
 对于有符号右移:
 正数:
  正数(原)的编码从第一到第三十二依次右移,再在最最前端补0
 负数:
  负数(补)的编码从第一到第三十二依次右移,再在最最前端补1
 
 左移都是在末尾补0。
 
 
 
 
 
java程序源代码:
 
 
 
package test03;
 
public class Test06_23 {
 
 

/**

  * int a = 0x81fd0000; // 1000 0001 1111 1101 0000 0000 0000 0000 a >>>= 1;

  * 变量a的值为:()。 (最高位为1)负数a,无符号右移后结果(直接补0)。 0100 0001 1111 1101 0000 0000 0000

  * 0000 01000000111111101000000000000000

  * 

  * 注意:负数在内在中永远是补码形式。只是人们发现,可以通过对正数的编码进行取反加1得到负数在内在中的形式。 也就是常说的负数以补码存在。

  * 

  * 

  * @param args

  */

 public static void main(String[] args) {

   byte b1 = 1;

   System.out.println(Integer.toBinaryString(b1));

   byte b = (byte) ~b1;

   System.out.println("下面是负-2的补码,也是负数的内存中实际存储的形式。");

   System.out.println(Integer.toBinaryString(b));

   System.out.println("下面是-2的反码:");

   System.out.println(Integer.toBinaryString(b - 1));

   System.out.println("下面是正2的原码:");

   System.out.println("前面省略30个0:……" + Integer.toBinaryString(~(b - 1)));

   System.out.println(b);

   System.out.println();

   System.out.println("##################");

   System.out.println("2的编码(原码)");

   System.out.println("000000000000000000000000000000"

   + Integer.toBinaryString(2));

   System.out.println("2右移1位后的原码(相当于除2)");

   System.out.println("0000000000000000000000000000000"

   + Integer.toBinaryString(2 >>> 1));

   System.out.println();

   System.out.println("2的编码(原码)");

   System.out.println("000000000000000000000000000000"

   + Integer.toBinaryString(2));

   System.out.println("2无符号右移1位后的原码(相当于除2)");

   System.out.println("0000000000000000000000000000000"

   + Integer.toBinaryString(2 >>> 1));

   System.out.println("################");

   System.out.println("负数有符号右移的步骤");

   System.out.println("-3的编码(补码):");

   System.out.println(Integer.toBinaryString(-3));

   System.out.println("-3右移1位后的补码(有符号,负数补1,正数补0)");

   System.out.println(Integer.toBinaryString(-3 >> 1));

   System.out.println();

   System.out.println("-3的编码(补码):");

   System.out.println(Integer.toBinaryString(-3));

   System.out.println("-3无符号右移1位后的补码(无符号都补0)");

   System.out.println("0" + Integer.toBinaryString(-3 >>> 1));

    

   System.out.println();

   System.out.println("########################");

   int a = 0x81fd0000;

   System.out.println("正数(-a)的编码(原码)");

   System.out.println("0" + Integer.toBinaryString(-a));

   System.out.println("负数a的编码(补码)");

   System.out.println(Integer.toBinaryString(a));

   System.out.println("负数a无符号右移(为正)后的编码(补码-并直接补0)");

   System.out.println("0" + Integer.toBinaryString((a) >>> 1));

   System.out.println();

   System.out.println("负数a的编码(补码)");

   System.out.println(Integer.toBinaryString(a));

   System.out.println("负数a右移(仍然为负)的编码(补码)");

   System.out.println(Integer.toBinaryString(a >> 1));

   System.out.println();

   System.out.println("负数a的编码(补)");

   System.out.println(Integer.toBinaryString(a));

   System.out.println("负数a左移1位后(仍为负)的编码(补)");

   System.out.println("000000" + Integer.toBinaryString(a << 1));

  

  }

}

 

© 著作权归作者所有

共有 人打赏支持
天堂之镜
粉丝 5
博文 6
码字总数 5734
作品 0
长沙
高级程序员
Java位运算符与移位运算符

位运算符 位运算符主要针对两个二进制数的位进行逻辑运算,它包括:与(&)、或(|)、非(~)、异或(^)** 运算规则: 计算机中的数字运算都是以补码的形式进行的,所以在做为运算时,首先将...

深情不及酒伴
2017/12/04
0
0
Java移位运算符总结

本文参考:java移位运算符详解 Java移位运算符有三种 << 左移运算符,value< >> 右移运算符,value>>num >>> 无符号右移运算符, value>>>num << 左移运算符。(value< 相当与2*2,即将2(v......

Mercy_丶
2016/06/27
43
0
原码, 反码, 补码 详解

一. 机器数和真值 在学习原码, 反码和补码之前, 需要先了解机器数和真值的概念. 1、机器数 一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最...

xunzaosiyecao
2017/10/24
0
0
计算机存储数据的格式

概述 计算机存储的格式是二进制位,8个二进制位表示一个字节,在计算机中二进制位有原码,反码和补码的格式,下面分别介绍 原码:最高位表示符号位,正数0,负数1;其余7位表示数值因此,一字...

rockjh
01/02
0
0
Java 基本类型与二进制数位的本质

1.Java中的基本类型以二进制补码的形式表示,最高位为符号位: 如12, 用二进制表示为:0000 1100 而-125, 用二进制表示为:1000 0011 另补充原码,反码,补码的含义:  原码:将一个整数,...

linsea
2013/11/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Java IO类库之PrintStreamWriter

* A <code>PrintStream</code> adds functionality to another output stream, * namely the ability to print representations of various data values * conveniently. Two other fea......

老韭菜
55分钟前
0
0
qduoj~前端~二次开发~笔记

青岛大学qdu的onlinejudge是js的写的前端,框架是vue.js,在nodejs上部署运行,其实整体运行还是建立在docker的容器虚拟环境里,这里暂时不需要docker。安装环境是Ubuntu14-64bit 1.安装一大...

虚拟世界的懒猫
59分钟前
6
0
ConcurrentHashMap源码解读

部分内容转自:http://jiabinyuan.xyz/#/app/archive/detail/25 内部结构 内部采用了segment结构,每一个segment相当于一个hashtable。看下面的结构图: 从图的结构我们可以了解到,Concurr...

edwardGe
今天
1
0
Ubuntu终端Tab键自动补全

打开 /etc/bash.bashrc,找到下列代码,取消注释。 #enable bash completion in interactive shells#if ! shopt -oq posix; then# if [-f /usr/share/bash-completion/bash_compl......

大熊猫
今天
0
0
polipo socks5代理转http代理

天朝的网络,哎~ 装个 yarn 都时而会卡 假设在SSlocal 已经装好运行的前提下,来安装设置 polipo sudo apt-get install polipo sudo vim /etc/polipo/config 追加下列配置内容,并保存 socksP...

纯洁徐
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部