负数的二进制表示方法

转自:http://blog.sina.com.cn/s/blog_56d8ea900100y65b.html

一:表示法:
1、正数5的表示法
假设有一个 int 类型的数,值为5,那么,我们知道它在计算机中表示为:
00000000 00000000 00000000 00000101
5转换成二制是101,不过int类型的数占用4字节(32位),所以前面填了一堆0。

2、负数-5的表示法
现在想知道,-5在计算机中如何表示?在计算机中,负数以原码的补码形式表达。

二、概念:
1、原码:一个正数,按照绝对值大小转换成的二进制数;一个负数按照绝对值大小转换成的二进制数,然后最高位补1,称为原码。
比如 00000000 00000000 00000000 00000101 是 5的 原码。
     10000000 00000000 00000000 00000101 是 -5的 原码。
 
   备注:
   比如byte类型,用2^8来表示无符号整数的话,是0 - 255了;如果有符号, 最高位表示符号,0为正,1为负,那么,正常的理解就是 -127 至 +127 了.这就是原码了,值得一提的是,原码的弱点,有2个0,即+0和-0(10000000和00000000);还有就是,进行异号相加或同号相减时,比较笨蛋,先要判断2个数的绝对值大小,然后进行加减操作,最后运算结果的符号还要与大的符号相同;于是,反码产生了。

2、反码:正数的反码与原码相同,负数的反码为对该数的原码除符号位外各位取反[每一位取反(除符号位)]。
取反操作指:原为1,得0;原为0,得1。(1变0; 0变1)
比如:正数00000000 00000000 00000000 00000101  的反码还是 00000000 00000000 00000000 00000101
      负数10000000 00000000 00000000 00000101  的反码则是 11111111 11111111 11111111 11111010。

反码是相互的,所以也可称:10000000 00000000 00000000 00000101 和 11111111 11111111 11111111 11111010互为反码。

备注:还是有+0和-0,没过多久,反码就成为了过滤产物,也就是,后来补码出现了。

3、补码:正数的补码与原码相同,负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1.
比如:10000000 00000000 00000000 00000101 的补码是:11111111 11111111 11111111 11111010。
那么,补码为:
11111111 11111111 11111111 11111010 + 1 = 11111111 11111111 11111111 11111011

备注:1、从补码求原码的方法跟原码求补码是一样的,也可以通过完全逆运算来做,先减一,再取反。
      2、补码却规定0没有正负之分

所以,-5 在计算机中表达为:11111111 11111111 11111111 11111011。转换为十六进制:0xFFFFFFFB。

三、再举一例
我们来看整数-1在计算机中如何表示。假设这也是一个int类型,那么:
1、先取-1的原码:10000000 00000000 00000000 00000001
2、得反码:     11111111 11111111 11111111 11111110(除符号位按位取反)
3、得补码:     11111111 11111111 11111111 11111111

可见,-1在计算机里用二进制表达就是全1。16进制为:0xFFFFFF

四、主要知识点:

正数的反码和补码都与原码相同。
负数的反码为对该数的原码除符号位外各位取反。
负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1

源码:优点在于换算简单 缺点在于两个零 加减法需要独立运算
反码:有点在于表示清晰 缺点在于两个零 加减法同样需要独立运算
补码:优点在于一个零 范围大  减法可以转为加法 缺点在于理解困难

下面是书上原文:

原码表示法规定:用符号位和数值表示带符号数,正数的符号位用“0”表示,负数的符号位用“1”表示,数值部分用二进制形式表示。
反码表示法规定:正数的反码与原码相同,负数的反码为对该数的原码除符号位外各位取反。
补码表示法规定:正数的补码与原码相同,负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1.
正零和负零的补码相同,[+0]补=[-0]补=0000 0000B

五、特殊情况-128
1000 0000,那么,它的原码是什么呢?从补码求原码的方法跟原码求补码是一样的。先保留符号位其它求反:  1111 1111, 再加1,11000 0000, 超过了8位了。对,用8位数的原码在这里已经无法表示了。

那么,回到原码处, 它的原码也是 1000 0000(超出的自动丢失),1000 0000 在原码表示什么呢? -0, 但补码却规定0没有正负之分。
转换一下思路,看看计算机里,是怎么运算的:
对于负数,先取绝对值,然后求反,加一
-128 -> 128 -> 1000 0000 -> 0111 1111 -> 1000 0000
现在明确了吧
所以, 8位有符号的整数取值范围的补码表示
1000 0000 到 0000 0000, 再到 0111 1111
即 -128 到 0, 再到 127
最终 -128 ~ +127

永远记住:程序里的加减法对二进制是永远有效的。但是并不一定适合于真实世界。

byte m = -128;
byte q = 1;
byte p = (byte)(m - q); //这一步其实编译器会报错,其实是发现越界了,我们强行转化为byte就可以看出结果。
System.out.println( p); p的结果为:127

时间: 2024-09-30 01:32:17

负数的二进制表示方法的相关文章

Java整数占几个字节,以及负数的二进制表示方法,以及Java的逻辑运算符>>和>>>的区别

Java整数占几个字节? 答:占4个字节,共32个比特位 1个字节占8个比特位(1B(byte)= 8 bit) 因此,类型和字节对应如下 byte 1 short 2 char 2 int 4 float 4 double 8 double  8 -----------------------------------------------------------------------以下是用System.out.println的SIZE输出-------------------------

十进制负数转换为二进制、八进制、十六进制的知识分享

这篇文章主要介绍了十进制负数转换为二进制.八进制.十六进制的知识分享,需要的朋友可以参考下 程序猿们或许对二进制都不陌生,二进制是计算技术中广泛采用的一种数制.二进制数据是用0和1两个数码来表示的数.但是很多人都会将二进制转换成整数,但是如何用二进制表示负数呢?有的人会说,在二进制前面加个负数符合.而计算机只能认识0 和 1,又怎么去加个额外的负数符号呢?于是我们就需要用0和1来表示负数.如果想要弄懂这个,我们需要先了解什么是二进制原码. 原码是什么 原码(true form)是一种计算机中对数

JAVA中负数转二进制分析

最近在看集合源码,发现ArrayDeque里面用到了大量的&运算,这牵扯到了二进制.突然发现自己对负数的二进制有点模糊了,对此进行了一些支持补充. 首先我们要对原码.反码和补码有个了解: 1.所谓原码就是二进制定点表示法,即最高位为符号位,"0"表示正,"1"表示负,其余位表示数值的大小. 2.反码表示法规定:正数的反码与其原码相同:负数的反码是对其原码逐位取反,但符号位除外. 原码10010= 反码11101 (10010,1为符号码,故为负) (1110

NDK使用二进制库方法(翻译)

NDK Prebuilt library support: NDK使用二进制库方法: Android NDK r5 introduced support for prebuilt libraries (shared and static), i.e. the ability to include and use, in your applications, prebuilt version of libraries. This feature can be useful for two thin

负数的二进制表示法

先了解几个概念 [1]原码: ·正数的原码,按照绝对值转换成二进制 ·负数的原码,按照绝对值转换成二进制,最高位补1(有符号的整形最高位用来表示正\负,0为正数,1为负) 示例: 整数5的原码 00000000 00000000 00000000 00000101 整数-5的原码 10000000 00000000 00000000 00000101 [2]反码: ·正数的反码,与原码相同 ·负数的反码,符号位不变,其余为取反 示例: 整数5的原码与反码表示 原码:00000000 000000

十进制转换为二进制的方法

方法1 java.lang包里integer类下有一个方法 toBinaryString public static String toBinaryString(int i) 以二进制(基数 2)无符号整数形式返回一个整数参数的字符串表示形式. 如果参数为负,该无符号整数值为参数加上 232:否则等于该参数.将该值转换为二进制(基数 2)形式的无前导 0 的 ASCII 数字字符串.如果无符号数的大小为零,则用一个零字符 '0' ('\u0030') 表示它:否则,无符号数大小的表示形式中的第一

负数的二进制表示

在二进制中,用最高位来表示整数和负数. 比如 System.out.println(Integer.toBinaryString(1)); System.out.println(Integer.toBinaryString(-1)); 会输出 整数前面的0被省略了. 或者这样 public void test(){ System.out.println(Integer.toBinaryString(Integer.MAX_VALUE)); System.out.println(Integer.t

记一次负数的二进制

这是去年的一个填空题,当然,只要知道换算二进制就完全没问题的~ 1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 5 void to2(int x) 6 { 7 int flage = 0; 8 flage = (x>0)?1:-1; 9 if(x == 0) flage = 0; 10 switch(flage) 11 { 12 case 0:cout<<" ";

负数的二进制如何转化为十进制

转发 -5 如何用二进制表示 取反加1 5 =0000 0101 取反 1111 1010 加1 1111 1011 所以这个就表示 -5 1111 1011  对应十进制中的多少        [减一取反] 首位是 1 ,故是负数 减一      1111 1010 取反           0000 0101=5 所以答案是    -5 原文地址:https://www.cnblogs.com/gongchengniu/p/12168991.html