关于补码的问题


方便起见,这里举例全部取8位二进制数

定义:

正数原、反、补一致,不说

负数

原:-7:1000 0111

反:-7:1111 1000 即符号位不变,其他取反

补:-7:1111 1001 即在反码基础上加一

补一个原码直接(不通过反码)求补码的方法,从右往左,遇0不变,遇第一个1也不变,接着逐个(不包括符号位)取反,符号位保留,即可。

另附:补码的补码是原码

说明几个让人疑惑的特例:

数字原码反码补码
+00000,00000000,00000000,0000
-01000,00001111,11110000,0000
-128not existnot exist1000,0000





上表可以看出,+0,-0是公用一个补码的,这样才是科学的,但机器中用补码表示数值是另外一个主因,即引入补码后,减法运算可以用加法实现。

例如:17+(-3)

原码运算补码运算
0001,00010001,0001
1000,00111111,1101
1001,0100(-20)1,0000,1110(+14)




原码错的有多离谱就不说了。

显然,在硬件中只要一个加法器,就能实现加、减法运算。

附:原码:The original code 反码:Anti-code 补码:Complement


笔者写了一个源程序,用以测试二进制十进制相互转化和原、反、补码的运算。

// test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "stdlib.h"//引入库,system("pause");用到
#include <cmath>
#include <iostream>
#include <string>
using std::string;

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	int b_to_d(string p);//二进制转换为十进制函数
	string d_to_b(int n);//十进制转换为二进制函数
	string anticode(string p);//求反码函数
	string complement(string p);//求补码函数
	string binary;
	int decimal=0;
	cout<<"说明:作者技术有限,时间也有限,没有写容错机制,输入二进制时必须是8位‘0’‘1’组成的字串,输入十进制时必须是-128~127之间的数!"<<endl;
	cout<<"先测试二进制向十进制的转换,请输入一个二进制数:"<<endl;
	cin>>binary;
	decimal=b_to_d(binary);
	cout<<"结果为:"<<decimal<<endl;
	cout<<"反码为:"<<anticode(binary)<<endl;
	cout<<"补码为:"<<complement(binary)<<endl;
	cout<<"现测试十进制向二进制的转换,请输入一个十进制数:"<<endl;
	cin>>decimal;
	binary=d_to_b(decimal);
		if(decimal==-128)
		cout<<"-128情况比较特殊,原码反码皆不存在!"<<"补码为:10000000"<<endl;
	else
	{
	cout<<"结果为:"<<binary<<endl;
	cout<<"反码为:"<<anticode(binary)<<endl;
	cout<<"补码为:"<<complement(binary)<<endl;
	}

	system("pause");//程序暂停,避免一闪而过
	return 0;
}

string d_to_b(int n)
{
	string temp="00000000";
	char c;
	int t,yu,i=0;
	if(n>127||n<-128)
	{
		cout<<"麻烦您输入一个-128~127之间的数,谢谢!"<<endl;
	}
	else
	{
		t=n;
		n=std::abs(n);
			while(n>1)
			{
				yu=n%2;
				n=n/2;
				if(yu==1)
					temp[i]='1';
				else
					temp[i]='0';
				i++;
			}
			temp[i]='1';
			if(t==0)
				temp[i]='0';
		if(t>=0)
			temp[7]='0';
		else
			temp[7]='1';
		for(i=0;i<4;i++)
		{
			c=temp[i];
			temp[i]=temp[7-i];
			temp[7-i]=c;
		}
	}
	return temp;
}

string anticode(string p)
{
	if(p[0]=='1')
	{
		for(int i=1;i<8;i++)
		{
			if(p[i]=='0')
				p[i]='1';
			else
				p[i]='0';
		}
	}
	return p;
}

char toggle(char c)//取反函数,注意这个函数没有在主函数声明,这是因为主函数没有用到这个函数,下面的complement用到了,所以在它前面就可以了
{
	if(c=='1')
		return '0';
	else
		return '1';
}

string complement(string p)
{
	bool state=false;
	if(p[0]=='0')
		return p;
	for(int i=7;i!=0;i--)
	{
		if(state)
			p[i]=toggle(p[i]);
		if(p[i]=='1')
			state=true;
	}
	if(!state)
		return "00000000";
	return p;
}


int b_to_d(string p)
{
	int temp=0;
	int i=1;
	while(i<8)
	{
		if(p[i]=='1'||p[i]=='0')
		{
			if(p[i]=='1')
				temp=temp+std::pow((double)2,(double)(7-i));
		}
		else
		{
			cout<<"您必须严格输入8位二进制数,程序比较小,没有容错机制!"<<endl;//检测到输入错误,提示错误并立刻跳出
		}
		i++;
	}
	if(p[0]=='0')
		return temp;
	else
		return (0-temp);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值