题目:
将十进制整数的内部32位二进制码输出。
输入格式:
输入数据中含有若干整数n,int型取值范围,整数之间空格符间隔或换行符间隔,以^Z或文件结束符结束输入。
输出格式:
对于每个n,输出其对应的32位二进制的机内码与原整数,二进制码每8位空1格,二进制码与原整数之间用“ <->”间隔。每个结果对应一行输出。末尾输出一行。
输入样例:
在这里给出一组输入。例如:
输出样例:
分析:
内码是指计算机汉字系统中使用的二进制字符编码。整数在计算机中的存在形式是以10010,01110101等二进制数的形式存在的,0和1的位数越多,对应的十进制数越大。在我们进行整数的内码相关计算时,就需要进行位运算。
呃。。。对于一个初学者来讲,仅仅从已学的内容进行位运算求补码是相当困难的,因此我们可以另辟蹊径,利用数组和反码补码原码的相互转换的原理来求一个整数的内码。
那么下面举例补码与原码的互换
原码求补码
求给定数值的补码分以下两种情况:
正数
正整数的补码是其二进制表示,与原码相同
例:+9的补码是00001001。(备注:这个+9的补码是用8位2进制来表示的,补码表示方式很多,还有16位二进制补码表示形式,以及32位二进制补码表示形式,64位进制补码表示形式等。每一种补码表示形式都只能表示有限的数字。)
9的二进制数为1001,不足八位左边用0补齐至七位,第一位用0表示正。
负数
求负整数的补码,将其原码除符号位外的所有位取反(0变1,1变0,符号位为1不变)后加1 。
同一个数字在不同的补码表示形式中是不同的。比如-15的补码,在8位二位运算中是11110001,然而在16位二进制补码表示中,就是1111111111110001。以下都使用8位2进制来表示。
例:求-5的补码。(5的二进制数为101)
-5对应带符号位负数5(10000101)→除符号位外所有位取反(11111010)→加 00000001为 (11111011)
所以-5的补码是11111011。
0的补码
数0的补码表示是唯一的。
[+0]补=[+0]反=[+0]原=00000000
[ -0]补=11111111+1=00000000
根据以上原理我们可以开始写程序了
我们要用的知识点只有数组,不用涉及位运算,由于负数和正数的内码计算方式有所区别,因此得分情况讨论,代码如下:
#include<stdio.h>
int main()
{
int a[32]={0},n,m=0,t,cnt=0;
while(scanf("%d",&n)!=EOF) //处理多组输入的情况
{
t=n; //记录n的值以便结尾输出
if(n>=0) //第一种情况n>=0
{
for(int i=31;i>=0;i--)
{
a[i]=n%2; //求补码
n=n/2;
}
}else //第二种情况n<0
{
n=-n; //先将n转为正数求补码
a[0]=1; //符号位是数组的第一位,1表示小于0
for(int i=31;i>=1;i--) //此时求其二进制数不改变第一位
{
a[i]=n%2;
n=n/2;
}
for(int i=1;i<32;i++) //除符号位外所有位取反
{
if(a[i]==1)
a[i]=0;
else a[i]=1;
}
for (int i = 31; i > 0; --i) { //取反后加1
if (a[i] == 1)a[i] = 0; //二进制中1+1=0,往前一位进1
else {
a[i] = 1;
break;
}
}
}
for(int i=0; i<32; i++) //正序输出对应操作后的数组
{
printf("%d", a[i]);
cnt++;
if(cnt%8==0)printf(" "); //每有8位输出一个空格
}
printf("<->%d\n",t);
}
return 0;
}
运行结果: