19章 位运算与进制转换

1.进制转换
1.1整数进制转换
例:10进制转16进制 (114514)10=(BF52)16
方法:除16取余法


1.2整数进制转换例题

方法1:

#include <stdio.h>
#include <ctype.h>
int main () {
    
    int n, m, i, sum = 0, time = 1;//sum是用来存放转换成十进制后的数
    char a[30];//输入的数组
    int b[30];//存放每一位转换成数是多少的数组
    int c[30];//转换成m进制后存放的数组
    
    scanf("%d%s\n%d", &n, a, &m);
    for(i = 0; a[i]; i ++ )//上面的链接解释了为什么要这样遍历数组
        if(a[i]>='0'&&a[i]<='9')//isdigit是判断是不是字符型数组的函数
            sum =sum*n + a[i] - '0';//转换成数
        else//是字母
            sum =sum*n + (a[i] - 'A') + 10;//转换成数,记得 + 10
    int len2 = 0;//转换成m进制时用来表示下一位放在哪里的指针
    
    while(sum >= 1) {//只要还没除完
        c[len2] = sum % m;
        sum /= m;
        len2 ++ ;
    }
    
    for(int i = len2 - 1; i >= 0; i -- )//倒着输出
        if(c[i] < 10) printf("%d", c[i]);//是数字
        else printf("%c", c[i] - 10 + 'A');//是字母
    return 0;
}

 
方法2

#include<bits/stdc++.h>

using namespace std;
//'0'=48 '1'=49 'A'=65
int char_to_int(char a){    //把字符转换为整数 
    return '0'<=a && a<='9'?a-'0':10+a-'A';
}

char int_to_char(int a){   //把整数转为要输出的数 
    return a<=9 ?'0'+a:a-10+'A';    //将ascii对应的整数转为字符型 
    //所以'0'+a=48+a 然后转化为字符


int main(){
    int output[33];
    int n,m,dec=0,num=0;//dec十进制数 
    string input;
    cin>>n>>input>>m;
    //把输入的数转化为十进制数 
    for(int i=0;i<input.length();i++){
        dec=dec*n+char_to_int(input[i]);
    } 
    //转化为m进制数
    while(dec!=0){
        output[num++]=dec%m;
        dec/=m;
    } 
    //输出转化好的进制数 
    for(int i=num-1;i>=0;i--){
        cout<<int_to_char(output[i]);    
    }
    cout<<endl;
    return 0; 

 
1.3十进制负数转二进制
第一步:求反码。第二步:求补码(也就是二进制数)
例:-20 不看负号转2进制 10100 因为有负号,则第一位为1,且要补满8位。
所以原码:10010100
然后反码:除第一位取反)11101011
补码(反码基础+1;11101100

1.4十进制小数转二进制
将小数位置*2,再取整数。
3.14)10=(11.00100011)2


1.5 十进制数转化为负r进制数
其实跟正进制差不多,但余数可能会小于0,则需要多一个判断条件,将负余数转为正数,也就是-r
还有商也要+1

    while(input!=0){
        // -5%-2 = -2* 2 - 1
        // 转为负余数 -2*3 + 1
        //所以商也要加 1 
        int k=input%r;   
        int c=input/r;
        if(k<0){
            k=k-r;
            c++;
        }
        input=c;
        output[num++]=k;    
    } 
2.位运算
c++中的位运算,也就是将整数在内存中的二进制位进行按位操作,换句话说也就是进行位运算时,整数会直接用二进制数表示。

2.1 按位与 &
同真为真,其余为假。

2.2 按位或 |
一真为真,全假为假。

2.3 按位异或 ^
一真一假为真,同真同假为假。
性质:a^b ^a=b(可以用来找奇数个的数值)

2.4 取反 ~
2.5位左移 <<
例:00101<<2相当于10100 ,也就是00101*2^2

2.6位右移>>
就是数/(2^n)

3.练习
3.1高低位交换(位运算)

注意:输入的数为整数,所以要用 unsigned int

#include<bits/stdc++.h>

using namespace std;

int main(){
    unsigned int n;   //
    cin>>n;
    cout<<(n<<16)+(n>>16)<<endl;
    return 0;

3.2进制转换(负进制)

思路:跟正进制差不多,只有一个要注意的地方:余数可能为负数。

#include<bits/stdc++.h>

using namespace std;

char int_to_char(int a){   //把整数转为要输出的数 
    return a<=9 ?'0'+a:a-10+'A';

int main(){
    int output[105];
    int input;
    int r,num=0;
    cin>>input>>r;
    cout<<input<<"=";
    while(input!=0){
        // -5%-2 = -2* 2 - 1
        // 转为负余数 -2*3 + 1
        //所以商也要加 1 
        int k=input%r;   
        int c=input/r;
        if(k<0){
            k=k-r;
            c++;
        }
        input=c;
        output[num++]=k;    
    }
    for(int i=num-1;i>=0;i--){
        cout<<int_to_char(output[i]);
    }
    cout<<"(base"<<r<<")"<<endl;

 
P1469 找筷子(位运算)异或的性质

思路:a^ b^a=b

#include<bits/stdc++.h>

using namespace std;
int main(){
    int n,x,ans=0;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&x);
        ans=ans^x;
    }
    printf("%d\n",ans);
}  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值