精华内容
下载资源
问答
  • 补码之取反加一
    千次阅读
    2020-10-19 14:30:21

    负数的表示 — 补码

    例如:一负数 -108
    原码:1 110 1100 符号位不变,其他位按位取反得:
    反码:1 001 0011 加1得:
    补码:1 001 0100

    设二进制补码序列b{w} = {b(w-1), b(w-2), …, b(1), b(0)}
    表示数值为:d = -b(w-1)*2^(w-1) + b(w-2)*2^(w-2) + … + b(1)*2^1 + b(0)*2^0 (式一)

    表示数值为:-1*2^7 + 1 0100B = -128 + 20 = -108

    取反对应的代数运算

    例如:1 110 1100
    取反:1 001 0011
    即:符号位不变, 将剩余的每个位1变0, 0变1;非负整数的反码不变;

    注意到:按位取反对应于
    111 1111 - 110 1100 = 001 0011 符号位不变即 1 001 0011
    即:2^(7) -1 - 110 1100 (式二)

    补码:1 001 0100
    (式二)加 1 后得到补码 即:2^(7) - 110 1100 符号位不变

    总结:负数原码取反加1 等效于 :2^(7) - 110 1100
    表示的数值为:-(2^(7) - 110 1100) = -1*2^(7) + 110 1100
    注意到:上式就是二进制补码编码的定义公式(式一)

    补码转原码 —— 取反加1或者减1取反

    根据以上论述可知:

    1. 取反加1 等效于:2^(7) - (2^(7) - 110 1100 ) = 110 1100 符号位不变;
      可以看出 :补码的补码就是原码
    2. 减1取反正好是求补码的逆向操作
      等效于: 2^(7)- 1 - (2^(7) - 110 1100 -1) = 110 1100 符号位不变
      可也看出:取反加1或者减1取反都可以实现补码变原码,而且都有简单的理论依据
    更多相关内容
  • 这个问题不是存储问题,而是程序设计人员的解释问题,类似这样的问题在后边的存储设备中也存在( 关注下一篇)百科概念计算机中的符号有三种表示方法,即原码、反码和补码。三种表示方法均有符号位和数值位两部分,...

    为什么需要补码

    在真实世界里,常常需要负数。如果存储在存储设备中的最小值为0,那么计算机如何存储负数呢?这个问题不是存储问题,而是程序设计人员的解释问题,类似这样的问题在后边的存储设备中也存在( 关注下一篇)

    百科概念

    计算机中的符号数有三种表示方法,即原码、反码和补码。三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位,三种表示方法各不相同。

    在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

    从百科解释来看是为了减少硬件电路设计,这是最终目的。从设计目的来看实在感慨设计师的巧妙。

    下面我们分析一下,为什么原码取反加一就能够减少硬件电路,换句话说,为什么取反加一就可以将减法转化为加法?

    定义和原理

    从百科来看,给补码下个定义比较困难,就好比解释什么是筷子一样。我们可以抛开计算机,从人类社会数学的概念出发,给补码定义如下:

    所谓补码就是某个数n,这个数加上-n=0。这也是补码的基本原理。

    我们将二进制的首位为0解释为正数,1解释为负数

    f774a73a06ad?from=singlemessage

    补码.jpg

    13 00001101

    -13 11110011(补码)

    ---------------

    1 00000000

    直接从以上等式来看,13和-13之间除了符号位不一样,其实位之间并无关系。而实际上他们之间的关系十分微妙。

    这里可能有人会想,为什么不直接将符号位取反即表示负数?比如+13(+一般省略)和-13在十进制中就是符号不一样。

    理论上单纯从解释的角度出发没有问题

    00001101 (+13)

    10001101 (-13)

    但无法将该种解释通过加法来实现减法.(因为二进制相加之后不为0)

    那么这种微妙的关系是什么呢?

    通过补码的定义

    n+(-n)=0

    这里的(-n)即为补码.我们反推过来,这里n已知,0已知(00000000).

    如何求-n?

    我们知道给定一个数n,让这个数变为0有两种办法

    做减法,将这个数的每一位减1,这个办法在百科的概念中可以被否决,因为要增加硬件成本.

    做加法,让结果溢出后即为0

    根据第二种办法我们得出

    最大的数+1即可溢出为0

    那么n+(-n)=0 成立,-n推导如下

    已知

    0=(11111111+1)

    11111111

    1

    ------------

    1 00000000

    =>

    n+(-n)=(11111111+1)

    已知

    n|~n=11111111

    n+(-n)=(n|~n)+1

    n+(-n)=(n+~n)+1(二进制按位或即按位相加)

    =>

    (-n)=~n+1 (等号两个n抵消)

    总结

    通过以上分析,真的感慨计算机大师的微妙设计。

    通过数学的巧妙设计使cpu中不需要减法器电路以减少设计成本。

    展开全文
  • 文章目录问题点概括具体处理流程1、判断高位是否为12、转为二进制3、取反+14、转回16进制或10进制整体DemoTHE END 问题点概括        在做3D智慧城市大数据数字孪生系统时,...

    问题点概括


           在做3D智慧城市大数据数字孪生系统时,需要对温湿度传感设备上报的数据进行处理。其中涉及到16进制高位为1补码取负数问题,这里做个简单记录,予以往后扬嘴一笑的回忆。

    在这里插入图片描述

    具体处理流程


           为了方便理解下面贴出通讯协议的温度解析部分介绍。

    在这里插入图片描述

    1、判断高位是否为1

           拿到数据的第一步先来判断高位是否为1,Java中代码实现如下。

    	//这里的byte 就是接收到的16进制数据(0xFF9C、0x00FA等)
    	if ((byte & 0x80) == 0x80) {
    		//这里处理高位为1以后的逻辑
    	}
    

    2、转为二进制

           确定高位为1后将16进制字符串数据转成2进制,具体代码如下。

    	/**
    	 * 16进制String转2进制bite
    	 * 
    	 * @param hex
    	 * @return
    	 */
    	public static byte[] hexStr2Byte(String hex) {
    		ByteBuffer bf = ByteBuffer.allocate(hex.length() / 2);
    		for (int i = 0; i < hex.length(); i++) {
    			String hexStr = hex.charAt(i) + "";
    			i++;
    			hexStr += hex.charAt(i);
    			byte b = (byte) Integer.parseInt(hexStr, 16);
    			bf.put(b);
    		}
    		return bf.array();
    	}
    

    3、取反+1

           对二进制数据取反并+1,具体实现代码如下。

    		// 2进制取反
    		String str2 = "";
    		byte temp;
    		for (int i = 0; i < bytes.length; i++) {
    			temp = bytes[i];
    			bytes[i] = (byte) (~temp);
    			str2 += Integer.toBinaryString((bytes[i] & 0xFF) + 0x100).substring(1);
    		}
    		System.out.println("取反后二进制:" + str2);
    		// 取反后+1
    		String add_1 = Solution(str2, "1");
    		System.out.println("取反后二进制+1:" + add_1);
    
    	/**
    	 * 两个二进制字符串求和
    	 * 
    	 * @param a
    	 * @param b
    	 * @return
    	 */
    	public static String Solution(String a, String b) {
    		StringBuilder ans = new StringBuilder();
    		int ca = 0;
    		for (int i = a.length() - 1, j = b.length() - 1; i >= 0 || j >= 0; i--, j--) {
    			int sum = ca;
    			sum += i >= 0 ? a.charAt(i) - '0' : 0;
    			sum += j >= 0 ? b.charAt(j) - '0' : 0;
    			ans.append(sum % 2);
    			ca = sum / 2;
    		}
    		ans.append(ca == 1 ? ca : "");
    		return ans.reverse().toString();
    	}
    

    4、转回16进制或10进制

           根据需求转回16进制或者其他进制数据即可,我这里直接转回10进制,实现代码如下。

    		// 将取反+1后的二进制字符串转10进制
    		int d = Integer.parseInt(add_1, 2);
    		System.out.println("二进制字符串转10进制:" + d);
    

    整体Demo


           为了方便理解,下面是我独立出来的整体实现代码,如有不对还望多多指教。

    public static void main(String[] args) {
    		byte[] bytes = hexStr2Byte(hexStr);
    		// 2进制取反
    		String str2 = "";
    		byte temp;
    		for (int i = 0; i < bytes.length; i++) {
    			temp = bytes[i];
    			bytes[i] = (byte) (~temp);
    			str2 += Integer.toBinaryString((bytes[i] & 0xFF) + 0x100).substring(1);
    		}
    		System.out.println("取反后二进制:" + str2);
    		// 取反后+1
    		String add_1 = Solution(str2, "1");
    		System.out.println("取反后二进制+1:" + add_1);
    
    		// 将取反+1后的二进制字符串转10进制
    		int d = Integer.parseInt(add_1, 2);
    		System.out.println("二进制字符串转10进制:" + d);
    	}
    
    	/**
    	 * 16进制String转2进制bite
    	 * 
    	 * @param hex
    	 * @return
    	 */
    	public static byte[] hexStr2Byte(String hex) {
    		ByteBuffer bf = ByteBuffer.allocate(hex.length() / 2);
    		for (int i = 0; i < hex.length(); i++) {
    			String hexStr = hex.charAt(i) + "";
    			i++;
    			hexStr += hex.charAt(i);
    			byte b = (byte) Integer.parseInt(hexStr, 16);
    			bf.put(b);
    		}
    		return bf.array();
    	}
    
    	/**
    	 * 两个二进制字符串求和
    	 * 
    	 * @param a
    	 * @param b
    	 * @return
    	 */
    	public static String Solution(String a, String b) {
    		StringBuilder ans = new StringBuilder();
    		int ca = 0;
    		for (int i = a.length() - 1, j = b.length() - 1; i >= 0 || j >= 0; i--, j--) {
    			int sum = ca;
    			sum += i >= 0 ? a.charAt(i) - '0' : 0;
    			sum += j >= 0 ? b.charAt(j) - '0' : 0;
    			ans.append(sum % 2);
    			ca = sum / 2;
    		}
    		ans.append(ca == 1 ? ca : "");
    		return ans.reverse().toString();
    	}
    

    THE END


    感谢查阅
    玉念聿辉:编辑

    展开全文
  • 二进制补码为什么是原码取反加一

    千次阅读 2020-03-23 20:37:09
    二进制补码为什么是原码取反加一、补码,反码。

    一.二进制和原码的定义

    二进制

    在二进制数中,每一位仅有01两个可能的数码。所以计数基数为2。低位和相邻高位间的进位关系是“逢二进一”。

    原码

    为了表示数的在二进制数的前面增加一位符号位。符号位为0表示这个数为正数,符号位为1表示这个数为负数。这种形式的数称为原码。

    二.反码和补码的形式

    反码

    正数反码是其本身,负数反码是将其原码除符号位,其余各位取反(0变1,1变0)。

    补码

    正数补码是其本身,负数补码是在其反码最后一位加1

    三.补码为什么是原码取反加一

    补码的出现

    当我们使用二进制原码进行相反数的加法运算如:1+(-1)时
    alt
    得到的结果为-2。显然这个结果是错误的。为了解决这个问题出现了补码。

    补码的原理

    我们知道当一个二进制数的位宽确定后那么它所能表示的数也就具有了范围。基于这个原理为了实现相反数相加结果为0,我们可以使相反数相加的结果溢出从而成为0。
    在这里插入图片描述
    在这里插入图片描述
    如上图,假设还是1+(-1)= 0,二进制数位宽为4位。通过计算可以得出-1应表示为1111。我们将1111称为4位二进制数-1的补码。
    其中10000等于24。通过分析可以得出负数n的补码为2n-|n|。

    反码的确定

    一个数与其取反相加即可得到该数对应位宽的最大二进制数。
    在这里插入图片描述
    观察发现一个负数的反码就等于它的原码除符号位,其余各位取反+1。
    同时为了在补码的计算过程中不出现加法计算所以将一个负数的原码除符号位,其余各位取反得到的数称为它的反码。

    四.总结

    当我们初次读到“二进制补码等于原码取反加一。”这句话时我们会下意识的产生一种反码产生于补码前的错觉。但是事实上在数制的发展思路中补码应该先于反码出现,甚至于我们可以理解为,为了补码在计算机中的计算方便所以产生了反码。

    强调:

    1.理解思路应该是补码先于反码。
    2.反码加一产生补码只是一种数字组合中的巧合,其本身并不重要,关键要理解补码的原理。
    3.反码变补码的+1是指在最后一位加一,不是加到个位。

    展开全文
  • 对于二进制原码10010求反码: ((10010)原)反=对正数(00010)原含符号位取反=反码11101(10010,1为符号码,故为负) (11101)二进制=-2十进制 对于八进制: 例如,Linux平台将默认目录权限设置为755...
  • 二进制 string="1111 1111",现在我要对这个二进制全部取反,和对二进制的后面四位取反。代码应该怎么写呢。最好是.Net自带的取反方法和进制转化方法。
  • 但是呢,还有一个问题,为什么补码的求法是按位取反再加一呢,其实当你不明白为什么各大书籍都要用按位取反加一来计算补码的时候,我们完全可以直接用0减去所求的相反的补码就得到所求的编码(补码)了。...
  • 补码为什么取反加一

    2021-05-22 16:15:32
    现在我们知道补码是怎么来的了,也就是为了保证两个相反对应二进制的和必须是0,然后又不知道谁给它起了补码这个名字。补码补码,有没有感觉两个相反是互补的呢,也就是任意两个相反加起来一定等0,其中一个...
  • 这是OJ的一道研究生期末题,因为十...原来的数字为 10, 10 的二进制表示为 1010,二进制位数长度为 4,则二进制表示 1010 取反以后得到的二进制数为 0101。转换为十进制数字的值为 5。 如果想要求 10 的 5 位二进制.
  • 今天看了《逻辑设计基础》才明白了为什么二进制负数的补码是符号位不变,其他位取反加一 1. 什么是补码? 补码:计算机是用来将减法转换成加法的一种手段,在计算机系统中,数值一律用补码来表示和存储。 2. 如何...
  • 首先先理解这句话的意思,“(1)补码的(2)补码就是原码”,其中第一个标注的"补码",就是名词...其实在二进制里,"减一取反"和"取反加一"等价,所以我们可以这么做 为什么等价呢? 假设一个N位的二进制数,可表示的...
  • 二进制的表示中,若为负数,则最高位为1 举个例子: char类型的数据,1个字节 ( 1个字节 = 8位的二进制 ) 76 (正数的原码、反码、补码都是一样的) 原码:0100 1100 反码:0100 1100 补码:0100...
  • 【判断题】操作系统、语言处理系统属于系统软件。【判断题】计算机外部设备的驱动程序都是 BIOS ...【填空题】二进制信息最基本的逻辑运算有三种,即逻辑加、取反以及( )。【单选题】下列选项中,( )不是计算机中采用...
  • 本文目录反码和补码存在的意义为什么负数的补码是原码按位取反加一?解释参考文献 反码和补码存在的意义 反码:解决负数加法运算问题,将减法运算转换为加法运算,从而简化运算规则; 补码:解决负数加法运算正负零...
  • 为什么会产生补码?补码怎么计算?二进制的相反怎么表示?
  • [本文主要内容包括: (1) 介绍神经网络基本原理,(2) AForge.NET实现前向神经网络的方法,...(取反加一应该是按位取反加一,下同)提到了:若想求一个负数的补码,则对其绝对值进行“取反加一”即可;提到了:基想求...
  • 写作时间:2020-08-15目录:1.问题:2.将二进制表达的负数换成十进制怎么弄?3.总结一下正文:1.问题:比如说。要表达0~255的十进制,在FPGA使用一个8bit[7:0]的二进制就可以。...取反加一比如: '1 0101...
  • 这是书上的话,附例题 【11100000】补 = -(00011111+1)=-00100000=-2的五次方=-32
  • java中实现将十六进制按位取反

    千次阅读 2021-03-03 09:36:27
    public static void main(String[] args) { ... //十六进制 byte [] bytes = parseHexStr2Byte(javaStr); byte temp; for(int i=0;i<bytes.length;i++){ temp = bytes[i]; bytes[i] = (byte...
  • 计算机只能识别0和1,使用的是二进制,而在日常生活中人们使用的是十进制,”正如亚里士多德早就指出的那样,今天十进制的广泛采用,只不过是我们绝大多数人生来具有10个手指头这个解剖学事实的结果。尽管在历史上...
  • 补码与负数转换取反加一原理

    千次阅读 2018-03-14 16:21:51
    这里简要总结,补码与负数转换之间 “取反加1”的原理 我们知道补码其实是用一个像钟表那样的数轴来标,比如: 末位为符号位。设我们要转化的是 −x−x-x, 则 xxx 其实表示的是−x−x-x 在数轴上到原点的距离...
  • 这门课尝试用另一种方式——相对于国内用原码反码补码的数电体系(后面就用这个简称了)——解释计算机是如何用二进制表示有符号。问题产生于他讲的这个案例:-(-2147483648)。 讲到这里我很想骂娘,因为有一万个...
  • 二进制数据是用0和1两个数码来表示的。 它的基数为2,进位规则是“逢二进一”,借位规则是“借一当二”,由18世纪德国数理哲学大师莱布尼兹发现。当前的计算机系统使用的基本上是二进制系统,数据在计算机中主要...
  • 为什么负数的补码是取反加一

    千次阅读 2020-07-03 13:27:29
    所谓反码就是二进制表示取反加一 以Integer的【-1】为例(Integer占4个字节,占用(4*8=32)位,第一位为符号位): 【-1】的正常二进制表示【1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1...
  • 1:正数的二进制取反((-128)+(127-27)) 2:加一((-128)+(127-27+1)) 【小补充一下】 那么如果在c中利用位运算的话怎么做呢 还是例如八位,这里设一个x为正数 1: x ^ 01111111 = y (x ^ 127 = y) 2: y ...
  • 本文主要向大家介绍了C/C++知识点之怎样理解八进制和十六进制,通过具体的内容向大家展示,希望对大家...比如05,0237所以C语言没有二进制输入,最多可用函数去实现。八进制的表达方法C/C++规定,一个如果要指...
  • 十六进制:由0-9与A-Z(a-z)共十六个字母和数字组成(字母不区分大小写,A-F/a-f分别代表10-15)02 二进制与八进制对应关系二进制八进制0000100120103011410051016110711103 二进制与十六进制转换二进制十六进制...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,587
精华内容 3,834
关键字:

二进制数取反加一