PTA c语言 用数组解决位运算

文章讲述了如何通过编程解决一个题目,给定一个整数,对它的二进制位进行置0、置1或取反操作。涉及到正数和负数的补码转换,以及正确处理位运算的技巧。
摘要由CSDN通过智能技术生成

给定一个数,将该数的某二进制位上置0、置1或取反。

输入格式:

第1行:输入一个十进制整数。(32位int取值范围,其二进制数补码表示)

第2行后:每行输入一个位操作运算要求。

格式:输入位操作运算类型(1表示置0, 2表示置13表示按位取反) 位数(从最低位向高位,范围从0~31

最终以键盘输入^Z 或 文件结束(EOF标志)。

输出格式:

输出位运算后的整数值。

输入样例:

在这里给出一组输入。例如:

 
  1. 3

  2. 1 0

  3. 1 1

  4. 2 3

  5. 3 1

  6. 3 2

  7. 2 0

输出样例:

在这里给出相应的输出。例如:

15

这一题相信大多数人是在学习位运算后写的,不过这题也可以通过位运算求解,不过相对于位运算代码量显得过多。

根据题目要求,要先输入一个整数,接着输入数字对整数的二进制进行操作。

置零:将某位数字变成0

置一:将某位数字变成1

取反:某位数字0变1,1变0

要解这道题目,对于数组来说,是不是要将输入的整数先转化为二进制存入数组,在对二进制的某位进行操作

而转化为二进制之前,我们首先要判断输入的整数是正是负数,毕竟二进制的转化规则不一样(转化规则这里不再介绍)

当n>=0时

注:求二进制的方法可以先取余2再整除2循环 

当n<0时

 在得到整数相应的二进制补码后,我们接下来要做的就是对二进制进行相应的操作

 在完成输入的相应操作后,就要把变化后的二进制重新转化为一个新的整数了

 注意:

这有两种不同的解法一种错误一种正确,我当时是第二种找不到错误后面问了老师才知道:

如果他从高位开始加,第一个数就是2的31次方-2147483648,因为补码最高位的权重是负的,int表示的范围是-2147483648到2147483647,2的31次方正好是2147483648,溢出1位,变成最小的负数-2147483648,但是如果低位开始加,不符合补码的真值计算过程,从高位开始加的话,由于一开始就溢出了,等于考虑到了最高位权重为负数的问题

 最终代码如下:

#include <stdio.h>
#include <math.h>
int main()
{
    int n,a,b,sum=0,number[32]={0},i,x=0;
    scanf("%d",&n);
    if(n>=0)          //正数补码
                {
                    number[0]=0;
                    for(i=31;i>=1;i--)
                       {
                            number[i]=n%2;
                            n=n/2;
                       }
        
                }
            else if(n<0)         //负数原码
                {
                    number[0]=1;
                    n=-n;
                       for(i=31;i>=1;i--)
                           {
                                number[i]=n%2;
                                n=n/2;
                            }
                    for(i=1;i<32;i++)       //负数反码
                    {
                        if(number[i]==1)
                        {
                        number[i]=0;
                        }
                            else if(number[i]==0)
                                {
                                    number[i]=1;
                                }
                    }
        for(i=31;i>0;i--)         //负数补码
            {
                if(number[i]==0)
                {
                    number[i]=1;
                    break;
                }
                    else 
                    {
                        number[i]=0;
                    }
            }
        
                }
                
    while (scanf("%d %d",&a,&b)!=EOF)      //最终以键盘输入^Z 或 文件结束(EOF标志)
    {
        switch (a)
        {
            case 1:number[31-b]=0;break;   //1代表所在位置置零 
            case 2:number[31-b]=1;break;   //2代表所在位置置一 
            case 3:                        //3代表所在位置取反 
            if(number[31-b]==0)
            {
                number[31-b]=1;break;
            }
            else if(number[31-b]==1)
            {
                number[31-b]=0;break;
            }
        }
    }
        for(i=0;i<32;i++)
        {
            sum=sum+number[i]*pow(2,31-i);
            
        }
    printf("%d",sum);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值