精华内容
下载资源
问答
  • 在 MATLAB 中计算有符号整数的二进制补码
  • 这些函数像内置的 MATLAB 函数 BIN2DEC 和 DEC2BIN 一样在二进制字符串和十进制数之间进行转换,但可以容纳负整数(通过二进制补码)和分数正负数(通过二进制补码固定点和字符串中的二进制小数点)。 请注意,许多...
  • 二进制补码

    2019-10-06 20:08:02
    二进制补码 二进制补码主要是为了解决负整数的加减法运算(减法转化为加法)。 补码表示法 原码表示法就是用二进制的最高位表示符号,0表示正数,1表示负数。以8位为例:1就是表示为0000 0001,-1表示为1000 0001...

    二进制补码

    二进制补码主要是为了解决负整数的加减法运算(减法转化为加法)。

    补码表示法

    原码表示法就是用二进制的最高位表示符号,0表示正数,1表示负数。以8位为例:1就是表示为0000 0001,-1表示为1000 0001.
    而补码的规则是正整数保持不变,针对负整数,除符号位外,其他位全部取反,然后+1。
    注:负整数中,原码转补码是符号位不变,按位取反+1.补码转原码也一样,符号位不变,按位取反+1.
    比如-1,取反结果为1111 1110(符号位不变),再+1,补码为1111 1111.
    特殊之处的说明:
    1.原码表示中,0和-0可以分别表示为0000 0000和1000 0000,同一个数有两种表示,不方便计算机处理。而转换为补码之后却是一样的,0的补码为0000 0000不变,-0:1000 0000反码为1111 1111,+1得补码0000 0000.因此不用特殊处理。
    2.除符号位外,7位二进制数能表示的范围是0~127,127的原码和补码都是0111 1111,正数符号位为0,所以8为二进制能表示的最大的正数就只能到127了。那负数的情况呢,这里有一个特殊的规定,就是在补码中用1000 0000表示-128。所以8位二进制数的范围为-128到127.

    补码的作用

    减法转换为加法:
    例:5-3转为5+(-3)
    0000 0101
    1111 1101
    1 0000 0010
    舍去最高位得0000 0010 也就是2.

    例:-5-2 转为-5 + (-2)
    1111 1011
    1111 1110
    1 1111 1001
    舍去最高位的1111 1001
    取反1000 0110 +1得到1000 0111 也就是-7

    展开全文
  • 今天一场技术笔试一道编程题难住了我,算出一个十进制数的二进制补码和对应的16进制,由于时间紧张,加上紧张,做的极差,因此mark以下

    十进制转二进制补码

    首先要明确的是:十进制直接转成二进制是转化为二进制原码,正数的原码和补码相同,但负数的原码按位取反末位加一才是补码。
    因此流程图大概如下:
    在这里插入图片描述

    整个代码我贴在最后

    主要逻辑代码:

    public static String convert(int num) {
    		StringBuilder resultString = new StringBuilder();
    		// 初始化补码数组,共12位
    		String[] complementStrings = new String[] { "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" };
    		boolean ifNegative = false;
    		if (num < 0) {
    			complementStrings[0] = "1";
    			num = -num;
    			ifNegative = true;
    		}
    		// 加入到补码的数组中,开头从12-strings.length开始
    		String[] strings = Integer.toString(num, 2).split("");
    		// 对应在strings数组中的下标
    		int j = 0;
    		for (int i = 12 - strings.length; i < 12; i++) {
    			complementStrings[i] = strings[j];
    			j++;
    		}
    		// 如果为负数,先全部取反,否则直接拼接
    		if (ifNegative) {
    			for (int i = 1; i < complementStrings.length; i++) {
    				if (complementStrings[i].equals("1")) {
    					complementStrings[i] = "0";
    				} else {
    					complementStrings[i] = "1";
    				}
    			}
    			// 送进函数加一
    			resultString.append(binaryPlusOne(complementStrings, 11, 1));
    		} else {
    			resultString.append(strings.toString());
    		}
    		return resultString.toString();
    	}
    
    

    重要代码1:末位加一

    为递归算法,递归逻辑为每次将一位执行与进位的加法并拼接,走完整个数组,返回。

    	/**
    	 * 
    	 * @param strings 二进制数数组
    	 * @param temp 对哪一位执行加法
    	 * @param carry 进位值
    	 */
    	private static String binaryPlusOne(String[] strings, int temp, int carry) {
    		if (temp < 0) {
    			StringBuilder tempBuilder = new StringBuilder();
    			for (int i = 0; i < strings.length; i++) {
    				tempBuilder.append(strings[i]);
    			}
    			return tempBuilder.toString();
    		} else {
    			// 计算加上进位后的值
    			int tempInt = Integer.parseInt(strings[temp]) + carry;
    			// 更新对应位置上的值
    			strings[temp] = String.valueOf(tempInt % 2);
    			// 更新进位
    			carry = (tempInt) / 2;
    			// 更新坐标
    			temp--;
    		}
    		return binaryPlusOne(strings, temp, carry);
    	}
    

    二进制转16进制

    同样也是递归的思想,每次将二进制字符串最后四位进行转化,并拼接,知道拼完为止。

    重要代码

    	/**
    	 * 将二进制转为16进制
    	 * 
    	 * @param binaryString
    	 * @param length
    	 * @return
    	 */
    	private static String binaryTo16(String binaryString, int length) {
    		if (length < 4) {
    			return binaryString;
    		}
    		return binaryTo16(binaryString.substring(0, length - 4), length - 4)
    				+ binaryTo16Map.get(binaryString.substring(length - 4, length));
    	}
    

    总体代码,粘了就能用

    输入为一个十进制数(其二进制位数在12位以内)
    输出为 12位二进制补码和二进制补码对应的16进制码的拼接(以分号隔开)

    示例:

    输入:-7
    输出:111111111001;FF9
    
    import java.util.HashMap;
    
    public class BinaryCodeTransfer {
    	public final static int totalNumber = 12;
    	public final static HashMap<String, String> binaryTo16Map = new HashMap<String, String>() {
    		{
    			put("0000", "0");
    			put("0001", "1");
    			put("0010", "2");
    			put("0011", "3");
    			put("0100", "4");
    			put("0101", "5");
    			put("0110", "6");
    			put("0111", "7");
    			put("1000", "8");
    			put("1001", "9");
    			put("1010", "A");
    			put("1011", "B");
    			put("1100", "C");
    			put("1101", "D");
    			put("1110", "E");
    			put("1111", "F");
    		}
    	};
    
    	public static void main(String[] args) {
    		System.out.println(convert(-7));
    	}
    
    	public static String convertToBase72(int num) {
    
    		return Integer.toString(num, 2);
    	}
    
    	public static String convert(int num) {
    		StringBuilder resultString = new StringBuilder();
    		// 初始化补码数组,共12位
    		String[] complementStrings = new String[] { "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" };
    		boolean ifNegative = false;
    		if (num < 0) {
    			complementStrings[0] = "1";
    			num = -num;
    			ifNegative = true;
    		}
    		// 加入到补码的数组中,开头从12-strings.length开始
    		String[] strings = Integer.toString(num, 2).split("");
    		// 对应在strings数组中的下标
    		int j = 0;
    		for (int i = 12 - strings.length; i < 12; i++) {
    			complementStrings[i] = strings[j];
    			j++;
    		}
    		// 如果为负数,先全部取反,否则直接拼接
    		if (ifNegative) {
    			for (int i = 1; i < complementStrings.length; i++) {
    				if (complementStrings[i].equals("1")) {
    					complementStrings[i] = "0";
    				} else {
    					complementStrings[i] = "1";
    				}
    			}
    			// 送进函数加一
    			resultString.append(binaryPlusOne(complementStrings, 11, 1));
    		} else {
    			resultString.append(strings.toString());
    		}
    
    		// 如果大于零直接求出十六进制,否则,放入16进制处理函数中
    		resultString.append(";").append(binaryTo16(resultString.toString(), 12));
    		return resultString.toString();
    	}
    
    	/**
    	 * 
    	 * @param strings
    	 * @param temp
    	 * @param carry
    	 */
    	private static String binaryPlusOne(String[] strings, int temp, int carry) {
    		if (temp < 0) {
    			StringBuilder tempBuilder = new StringBuilder();
    			for (int i = 0; i < strings.length; i++) {
    				tempBuilder.append(strings[i]);
    			}
    			return tempBuilder.toString();
    		} else {
    			// 计算加上进位后的值
    			int tempInt = Integer.parseInt(strings[temp]) + carry;
    			// 更新对应位置上的值
    			strings[temp] = String.valueOf(tempInt % 2);
    			// 更新进位
    			carry = (tempInt) / 2;
    			// 更新坐标
    			temp--;
    		}
    		return binaryPlusOne(strings, temp, carry);
    	}
    
    	/**
    	 * 将二进制转为16进制
    	 * 
    	 * @param binaryString
    	 * @param length
    	 * @return
    	 */
    	private static String binaryTo16(String binaryString, int length) {
    		if (length < 4) {
    			return binaryString;
    		}
    		return binaryTo16(binaryString.substring(0, length - 4), length - 4)
    				+ binaryTo16Map.get(binaryString.substring(length - 4, length));
    	}
    }
    
    
    展开全文
  • 十进制数-38的8位二进制补码是首先,写出原码 :? 1010 0110?? ,???? 最高位的1表示负号?负数的补码是其原码的各位取反,再加1 ,(最高位符号位除外),所以,?十进制数-38的8位二进制补码是?? 1101 1010关于二进制...

    十进制数-38的8位二进制补码是

    首先,写出原码 :? 1010 0110?? ,???? 最高位的1表示负号?负数的补码是其原码的各位取反,再加1 ,(最高位符号位除外),所以,?十进制数-38的8位二进制补码是?? 1101 1010

    关于二进制补码,它可以用来表示小数吗二进制补码可以用来表示小数吗?还有给我一段二...

    【二进制补码可以用来表示小数吗?】

    可以,不过需要你自己来处理.方法是,按照所需要的精度,将该小数放大若干倍,当整数处理.

    为方便通常放大2的若干次方倍.

    这样,你就可以把这个整数看成“定点小数”,即保留了若干位二进制小数的定点数.

    有些资料上,将这种格式称作Q格式.如“Q8格式”就是保留了8位小数位的定点数.

    这种定点小数,做加减法时,需要小数点对齐,必要时需先做移位操作.

    乘除法时,也要掌握小数点位置.例如“Q8格式”和“Q4格式”的数相乘,其积应该看做“Q12格式”的.

    需注意C语言中的移位操作中,其“右移”分为“算术右移”和“逻辑右移”两种.对于“有符号”数,实行的是“算术右移”,对于“无符号数”,实行的是“逻辑右移”.

    如果您的程序中定义变量类型时定义的正确,那么你这些右移操作就不会错误.

    如果您的程序中有“无符号”和“有符号”混用的地方,或强制类型转换的地方,需要注意这点不要出错.

    “算术右移”和“逻辑右移”的区别:

    “逻辑右移”时最高位一律补零.

    “算术右移”时最高位保持不变,即:负数补1,正数补零.

    例如,用Q4的格式来表示0.75,放大2的4次方倍,为12,

    机器码是0000000000001100

    可以看做是定点小数000000000000.1100

    另,用Q4的格式来表示-0.75,放大2的4次方倍,为-12,

    机器码是1111111111110100

    可以看做是定点小数111111111111.0100

    如上,按Q4格式,用12代表0.75,用-12代表-0.75.

    要做(0.75)×(-0.75)用(12)×(-12)代表,乘得(-144).

    -144的机器码是1111111101110000

    看做Q8格式的定点小数11111111.01110000

    可以代表-0.5625.(等于-144/256,即-9/16)

    假如下面又要做别的运算,需要把这个Q8的定点小数化为Q4格式,那么,可以用>>4的运算,把这个数“算术右移”4位,得111111111111.0111.(这个数,如果当普通整数看,就是-9.)

    请注意这里右移的时候最高位补了4个1.

    【给我一段二进制补码,我怎么将其还原成十进制的数值?】

    首先,要知道其字长.以16位字长为例:

    16位字长如果是无符号数,可以表达的十进制数的范围是0 ~65535;

    如果是有符号数,可以表达的十进制数范围是-32768 ~ +32767.

    这里65536是2的16次方,32768是2的15次方.

    正整数的二进制化十进制想您应该知道吧?例如10010000化为十进制就是

    ((((((1×2+0)×2+0)×2+1)×2+0)×2+0)×2+0)×2+0 = 144

    给你一个有符号数的补码表示法的16位二进制代码,暂时先按照上述无符号数(即正整数)的规则,化为十进制;

    然后,看其符号位(最高二进制位)是否是1:

    如果是0,就表示它是正数.结果就对了.

    如果是1,就表示它应是负数,将此暂时值再减去65536,所得结果(负数)就是应有的结果了.

    上述“看其符号位是否是1”的判断,也可以代之以“看暂时值是否不小于32768”.

    例如:1111111111110111按照上述规则,得暂时值为65527.

    因为符号位是1,说明它应该是负数:65527 - 65536 = -9.

    对于n位二进制有符号补码除法x/y,要求不溢出的条件如下图,求解释为什么不溢出的条件是这样的

    y在分母,分母不能为0,就是y≠0了。这和数学当中的要求是一样的,编程时也要用条件语句来判断,然后再计算。

    C语言求二进制补码?源代码

    输入任意整数,输出32位的补码。

    输入其他,结束程序。

    #include

    int main()

    {

    int i,num=0;

    char s[33]={0};

    while(1==scanf("%d",&num)){

    for(i=0;i<32;i++){

    s[i]= (0x01 & (num>>(31-i))) ? '1' : '0' ;

    }

    printf("%s\n",s);

    }

    return 0;

    }

    展开全文
  • 二进制补码到十进制补码及其内的运算——关于补码的一点学习
                   

     

    问题:输入两个整数a,b-10100<a, b < 10100, 编程计算a-b

    这是个非常简单的题目,因为a,b可能为正可能为负,所以有a-b, a-(-b), -a-b,-a-(-b)这四种情况。去括号后有a-b,-(a-b), a+b, -(a+b),其中共两种情况。写代码的话仍然比较烦。想到二进制的补码运算可以把减法变成加法从而统一加减运算,于是考虑实现十进制的补码运算。十进制的补码运算以及各种进制的运算(做这个题目时查看TAOCP第二卷时学到了关于任意进制的一些东西,包括b进制和bk进制的转换,尤其是-10进制,sqrt(2)进制等等,非常有趣,附在后面)在网上资料非常多,这里只是记下自己做这个题目的过程,备忘。

    二进制的补码运算是非常熟悉的了。(X+Y)X+Y(X-Y)X+(-Y),这是补码能统一加减运算的公式,对于十进制也是一样。对于任何进制的补码,都有公式:

    [X]=M+X(MOD M)

    有了这些,将补码应用于十进制就非常简单。自己当时有些偏执,一定想找两个数放在符号位上,替代二进制中01负的作用。因为二进制中,0表示什么都没有,1表示再放一个就会溢出,所以十进制中,用0取代二进制中的0,放在符号位上表示正,用9取代二进制中的1,放在符号位上表示负(其实自己把问题弄复杂了,大可不必如此)。这样,包括符号位在内的n个十进制位补码能表示的范围是[-10n-1, 10n-1-1]总共10n个数。例如,计算-46-37这个式子:-46的原码就是946,补码按位取反末位加1,得到954-37的原码为937,补码为963,补码相加得(-46)+(-37)补=954+963=1917,符号位进位舍掉,得到结果是917917的再按位取反末位加1得原码983,它表示的真值是-83,所以有-46-37=-83

    以上如果想计算-99-99就会溢出,如此必须用四位十进制位表示。但一个字节对计算机来说九牛一毛,所以到这里直接就写程序了。代码如下:

    #include <stdio.h>#include <string.h>char a[128], b[128], ta[128], tb[128];int main() { int i, j; scanf("%s%s", a,b); if(*a == '-') {  ta[103] = 9;  for(i = 0, j = strlen(a) - 1; j >= 1; i++, j--)   ta[i] = 9 - (a[j] - '0');  while(i <= 102) { ta[i] = 9; i++; }  ta[0] += 1; } else {  ta[103] = 0;  for(i = 0, j = strlen(a) - 1; j >= 0; i++, j--)   ta[i] = a[j] - '0'; } if(*b == '-') {  tb[103] = 0;  for(i = 0, j = strlen(b) - 1; j >= 1; i++, j--)   tb[i] = b[j] - '0'; } else {  tb[103] = 9;  for(i = 0, j = strlen(b) - 1; j >= 0; i++, j--)   tb[i] = 9 - (b[j] - '0');  while(i <= 102) { tb[i] = 9; i++; }  tb[0] += 1; } for(i = 0; i <= 103; i++) {  tb[i] += ta[i];  tb[i + 1] += tb[i] / 10;  tb[i] %= 10; } // print if(tb[103] == 0) {  for(i = 102; tb[i] == 0; i--);  while(i >= 0) { putchar(tb[i] + '0'); i--; }  putchar('/n'); } else {  for(i = 0; i <= 102; i++)   tb[i] = 9 - tb[i];  tb[0] += 1;  for(i = 0; tb[i] >= 10; i++) {   tb[i+1] += tb[i] / 10;   tb[i] %= 10;  }  putchar('-');  for(i = 102; tb[i] == 0; i--);  while(i >= 0) { putchar(tb[i] + '0'); i--; }  putchar('/n'); } return 0;} 

    这段代码只是为了AC

    现在小结一下。二进制补码定义形式非常漂亮,因为它具有对称性。在二进制里面,很多的东西都是“恰好如此”。恰好二进制只有01两个数,恰好只有正负两种状态,恰好2n+2n=2n+1……。在补码的对应规则下,n个数位能表示的数的个数还是那么多,只不过把其中的一半的正数的形式让给了负数。在这个意义下再看十进制的补码,如果是n位十进制数,它能表示10n个十进制数字串,如果使用补码,它必须分一半出来用于表示负数,所以它只能表示0.5 * 10n = 5 * 10n-1个正数。另外的一半就是负的了。我们常说的在补码表示中“符号位参与运算”这个优点,其实并没有什么,只不过权值最高的数位恰好同时能够表示一个数的正负而已,它本来就是应该而且必须参与到运算中去的。

    模仿二进制补码的形式定义十进制的补码如下:对于定点整数n+1位的十进制定点整数X=XnXn-1…X0,其补码为:

    [X]X, 如果0 <= X <=5 * 10n-1

    [X]10n+1 + X = 10n+1 - | X |,如果 -5 * 10n <= X<= -1

    当最高位Xn01234时,表示正,为56789时,表示负。例如三位十进制数补码能表示-5004991000个数。例如下列计算:

    -327+164: -327的补码是673-327à673, +164à164,-327+164à673+164=837, 837是负数,并且它是补码形式,它的绝对值的真值是163.所以-327+164=-163

    当运算结果的绝对值大于500时,会发生溢出。可以使用类似计算机组成原理中的双符号位检测是上溢还是下溢,但通常没有必要,不如把多出来的符号位用来参加计算,使得能够表示的数的范围扩大十倍,以前的溢出自然就没有了。

    下面是读到KnuthTAOCP第二卷的这一节时了解到的其它十分有趣的知识。自己只是走马观花看了一下,把记下来的记在这里:一,b进制和bk进制的互相转换非常简单,看2进制和8进制、16进制的互相转换就明白了。二,-10进制和-2进制是被发现非常有意思的。-2进制似乎也得到了应用。其它比如sqrt(2)i进制等等,非常神奇。这些进制的定义和其它进制一样,只不过每个数位上的权不一样了。例如,要把126这个十进制数转变成-10进制,还是那样除基取余的方法即可,126 / (-10) = -12……6,-12 / (-10) = 2……8,所以十进制的126-10进制下的表示是286.可以验算一下,2 * (-10)2 + 8 *(-10)1 + 6 = 126.不过-10进制数的运算规则自己还没学会。

    关于原码转变成补码的方法,在网上都能找到证明。

     

               

    再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

    展开全文
  • 二进制补码计算原理详解

    万次阅读 多人点赞 2018-07-03 17:34:54
    二进制负数的在计算机中采用补码的方式表示。很多人很好奇为什么使用补码,直接使用原码表示多好,看上去更加直观和易于计算。然而事实告诉我们,这种直观只是我们人类的一厢情愿罢了,在计算机看来,补码才是它们最...
  • 关于二进制补码

    热门讨论 2016-09-29 23:53:10
    关于二进制补码16340146 学院 目录关于二进制补码 二进制补码介绍1 二进制补码的证明 数字溢出2 附表 Binary Octal Hexa 0000 0 0 0001 1 1 0010 2 2 0011 3 3 0100 4 4 0101 5 5 0110 6 6 ...
  • 使用二进制补码表示二进制负数方法合理性的证明 目录 使用二进制补码表示二进制负数方法合理性的证明 二进制补码的定义 补码与反码的关系 定理 1 计算机中二进制负数 定理2 注释 二进制补码的定义...
  • 十进制转二进制补码(正负都可) 指针初学 将一个十进制正(负)整数转换为对应的二进制补码(用指针完成 十进制转二进制:1.先判断该整数是正数还是负数 如果是正数则二进制补码首位为1 , 且对应的二进制补码就是原. 如果...
  • 二进制补码计算器 该库包含用于计算十进制数的二进制补码的函数,反之亦然; 二进制补码表示形式既可以二进制表示,也可以十六进制表示。 这些函数支持使用-2147483648至2147483647的32位整数,因为它们使用了...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,578
精华内容 4,631
关键字:

二进制补码