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;
}
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
方法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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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);
}   
posted @ 2025-06-01 16:12  kkman2000  阅读(15)  评论(0)    收藏  举报