谈谈补码与移位

在计算机中整数的表示使用补码来表示的。

什么是补码呢?首先要明白什么是原码。

数字是有符号的,计算机中,用最高位作为符号位。以四位机器码举例:1的原码表示是:0001; -1 的原码表示是:1001。

也就是说表示实际数值的只有3位。因此4位机器码原码表示数的范围是:[-7, 7],其中0有两种表示,+0:  0000; -0:   1000。

原码表示清晰易懂,但对机器来说却是个麻烦,因为我们必须设计两套电路分别表示加法和减法。

为了统一加减法电路,人们想到了同余原理,让符号位也参与运算,补码应运而生。(反码没有实际应用,没必要记,这里就不解释了,实际上如果不是为了引出正数的补码表示,原码也没必要记)

对于正数,补码表示就是其原码,还以四位机器码举例:1的补码表示是:0001。

对于负数,补码表示就是对于相应的正数表示,连同符号位一起,各位取反后加1。 -1的补码表示为: 1111。(0001 各位取反,1110, 再加1)

对于补码来说,我们没办法直接看出负数的值,想知道负数的真值,我们需要对负数求补,再加上符号位即可。

以-3举例:1101。最高位是1,我们知道它是个负数。对其求补:0010 + 1 = 0011。我们也就知道了其值为-3。

也就是说,正数求补就是其对应的负数,负数求补就是其对应的正数。

对于减法,加上其负数的补码即可。我们成功的把减法运算变成为了加法运算。(不理解同余原理的,可能难以理解。记住结论即可,我不详细展开介绍了)

对于4位机器码来说,补码表示范围为:[-8, 7]。这里0只有一种表示:0000. 所以比原码多表示了一个负数:-8 : 1000。+8的补码为 01000,由于溢出的原因,无法表示。

下面给出8位机器码表示的几个数字的补码:

0           0000 0000

1           0000 0001

2           0000 0010

... ...

127       0111 1111

-1          1111 1111

-2          1111 1110

... ...

-128      1000 0000

有了补码之后,计算机中的加减乘除都可以用加法和求补电路实现,大大简化了电路设计。

下面谈谈移位。这里不多谈,就只谈谈java中的移位操作。

java这种语言竟然有移位操作,确实出乎人意料。不过考虑到java设计初衷是用于嵌入电视机机顶盒的,有这种面向底层的操作倒也不奇怪。

谈到移位,不得不提位运算符 | 或;  & 与; ^ 异或; ~ 取反。

这四种都是按位执行,也很简单,不详细展开。记住异或,异1同0即可。

java中左移 << :  高位舍去,低位补0。相当于乘2,当然前提是不溢出。 

java中右移 >>: 正数补0,负数补1,低位舍去。相当于除2,易知正数右移,最小得0;负数右移,最小得-1。

上面两种移位操作,称为算术移位,因为它们保存了算术符号,这与C C++是一样的。(左移在不溢出的情况下,符号是不会变化的。不过要注意溢出的发生。)

java中还有一种逻辑右移:>>> , 无论正负,高位补0,低位舍去。这是C C++ 没有的。

时间: 2024-08-03 09:40:29

谈谈补码与移位的相关文章

二进制、补码和移位

在计算机中,有符号数是以补码表示的. 1. 原码 原码的第一位是符号位,其余位表示值.比如8位二进制: [+1]原=0000 0001 [- 1]原=1000 0001 2. 补码 正数的补码就是它本身,负数的补码是在原码的基础上,符号位不变,其余各位取反+1. [+1]补=0000 0001 [- 1]补=1111 1111 补码转换为原码的规则依然是符号位不变,其余各位取反+1. 3. 移位 有符号数移位时,都是按照补码的形式移位: 右移:最右边的一位舍弃,最左边补符号位. 左移:最左边的一

2进制,10进制,16进制,补码和移位

逢二进一,逢十进一,十六进制 10110101(2) = 128+32+16+4+1 = 181(10) b 5(16) = b*16+5 = 11*16+5 = 181(10) 2进制 int n = 45; System.out.println(Integer.toBinaryString(n)); 计算机的内部(Java)只有2进制数据, 在显示的时候编程语言提供API将2进制转换为10进制显示出来. 计算机只能处理2进制数据, 利用编程语言提供的算法支持了10进制 Java中用于支持2进

补码的减法

先来谈谈补码的非 补码的非 根据CASAPP,第59页,有如下公式 二进制的减法 减法运算其实是可以由加法运算替代的,我们上面已经介绍过了无符号和补码的非,其实很多CPU是没有减法运算器的,它们都是将减数进行逆运算以后送入加法器,然后进行加法运算,这样得出来的结果就是减法运算最终的结果. X + Y 就是 X+Y的加法逆元(非) 一种特殊情况 TMIN应该注意,他的加法逆元是他本身.这点在CASPP练习题2.32上有体现 我们来看一下原题 练习题2.32 你现在有个任务,编写函数tsub_ok的

一篇文章搞懂移位运算

前提知识: 1. 计算机中对于有符号数的表示有三种方式,原码,补码,反码. 2. 在Java中,二进制数最高位是符号位,0表示正数,1表示负数: 3. 正数的表示,例如byte/int 数3,  二进制就是 0000 0011,负数的表示稍微麻烦一点(负数在计算机中是以补码的形式存储的) -5 的二进制: 1. -5的绝对值二进制表示  0000 0101 2. 然后求这个数的反码  1111 1010 3. 将反码加1 变成  1111 1011 , 这个就是-5的二进制表示(补码) 移位运算

1.3 算术运算和逻辑运算

1. 算术运算要点 (1)移位操作 ① 原码移位:原码进行算术左移和算术右移都不改变原码本身形态.左移一位相当于乘以 2,右移一位相当于除以 2,移位出现的空位补 0.这是因为原码与二进制数真值的绝对值是完全一样的,算术移位并不涉及数的符号. ② 补码移位:由于正数的补码与原码是一样的,所以正数的补码左.右移位所出现的空位补 0 均不会改变补码的形态.值得注意的是负数补码的移位,当负数的补码右移时所出现的空位必须补 1 才能保证数值的正确及形体的保持. ③ 反码移位:由于正数的反码与原码相同,所

Java小程序2(2015-8-6)

1. public class DataDemo2 { public static void main(String [] args){ char c1='A'; char c2=97; char c3='\u0041'; char c4=65; System.out.println(c1); System.out.println(c2); System.out.println(c3); System.out.println(c4); } } 2. public class LuoJiTest{

数字、基数及表示

数字.基数及表示 整数 整数是这些熟悉的数字 …, -1, 0, +1, +2, ….整数值也被称作是‘完整的’,并且分为正数(1到无穷大),负数(-1到负无穷大),零(0),非负数(零或正数)和少有的非正数(零或负数).正数和非负数间的差别通常非常重要,例如C语言典型地用非负数作为数组下标,明确地包括零. 基数 我们书写整数(和其它数字)时通常使用‘基数10’或‘十进制’算术.这是一种位置符号,每一个‘位置’的值比下一个大十倍.最后一个数字是一的个数,倒数第二个是10的个数,依此类推:因此数字

计算机硬件常识

3.什么是机器数? 答:计算机可以直接识别的数称为机器数.   4.数值数据的三要素? 答:计数进位制:小数点位置 : 符号.   1.什么是总线?它有什么用途?试举例说明. 答:总线是连接两个或多个功能部件的一组共享的信息传输线.用途:实现部件之间的信息传输.如ISA,PCI AGP等总线   2.总线通信采用的方式有哪几种?各有什么优缺点? 答:一般采用三种方式:同步通信方式.异步通信方式.半同步通信方式. 通信双方由统一的时钟控制数据传送称同步通信方式.这种通信方式的优点是规则明确.统一,

JDK源码解读之Integer(1)

本系列文章使用的JDK版本为jdk1.8.0_131,一些基础的知识储备:原码.反码.补码,移位,建议参考文章:<原码,反码,补码 详解><Java 源码学习系列(三)--Integer> Integer是我们开发过程中最常用的一个类,因此JDK的源码解读就从它开始吧.凡是对Java有点了解的都知道,Integer是int的包装类型,长度为32位.因此我们可以看到如下定义 //可表示的最小值:-2^31,至于为什么是这个数,上面的文章讲的很清楚了 @Native public st