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);
}