C++算法·进制转换
引言
基础的十进制,即逢十进一
日常生活中用的就是十进制(不包括时间、角度等)
还有电脑中的机械语言用的二进制,即逢二进一
例如(101)2(101)_2(101)2表示二进制101101101,即十进制的(5)10(5)_{10}(5)10
至于怎么转换进制,就是本文要讲的内容
定义&规律
引言中有提到,有多种进制,如十进制、二进制等
具体的xxx进制就是每逢xxx进一位
我们用基础的十进制列表与八进制对比下
十进制 | 八进制 |
---|---|
(0)10(0)_{10}(0)10 | (0)8(0)_8(0)8 |
(1)10(1)_{10}(1)10 | (1)8(1)_8(1)8 |
(2)10(2)_{10}(2)10 | (2)8(2)_8(2)8 |
(3)10(3)_{10}(3)10 | (3)8(3)_8(3)8 |
(4)10(4)_{10}(4)10 | (4)8(4)_8(4)8 |
(5)10(5)_{10}(5)10 | (5)8(5)_8(5)8 |
(6)10(6)_{10}(6)10 | (6)8(6)_8(6)8 |
(7)10(7)_{10}(7)10 | (7)8(7)_8(7)8 |
(8)10(8)_{10}(8)10 | (10)8(10)_8(10)8 |
(9)10(9)_{10}(9)10 | (11)8(11)_8(11)8 |
(10)10(10)_{10}(10)10 | (12)8(12)_8(12)8 |
(11)10(11)_{10}(11)10 | (13)8(13)_8(13)8 |
.................. | .................. |
通过列表可以发现,在0∼70 \sim 70∼7的十进制时,八进制与十进制的表示方法相同
但是到888时,八进制向左进位,最右边那一位变成000
十进制则到101010才进位,这里就可以发现逢xxx进111的规律了
下面来些例题:
例题1:二进制 → 十进制 (基础)
题目: 将二进制数 1101.101
转换为十进制数。
解答:
转换分为整数部分(1101)和小数部分(.101)。
-
整数部分 (1101):从右向左,每位乘以2的位次幂(从0开始)。
- 1 × 2⁰ = 1 × 1 = 1
- 0 × 2¹ = 0 × 2 = 0
- 1 × 2² = 1 × 4 = 4
- 1 × 2³ = 1 × 8 = 8
- 整数部分总和:8 + 4 + 0 + 1 = 13
-
小数部分 (.101):从左向右,每位乘以2的负位次幂(从-1开始)。
- 1 × 2⁻¹ = 1 × (1/2) = 0.5
- 0 × 2⁻² = 0 × (1/4) = 0
- 1 × 2⁻³ = 1 × (1/8) = 0.125
- 小数部分总和:0.5 + 0 + 0.125 = 0.625
-
合并结果:13 + 0.625 = 13.625
答案:(1101.101)₂ = (13.625)₁₀
例题2:十进制 → 二进制 (基础)
题目: 将十进制数 18.625
转换为二进制数。
解答:
转换分为整数部分(18)和小数部分(.625)。
-
整数部分 (18):用“除2取余,逆序排列”法。
- 18 ÷ 2 = 9 … 余0 (最低位)
- 9 ÷ 2 = 4 … 余1
- 4 ÷ 2 = 2 … 余0
- 2 ÷ 2 = 1 … 余0
- 1 ÷ 2 = 0 … 余1 (最高位)
- 将余数从下往上排列:
10010
- 所以
(18)₁₀ = (10010)₂
-
小数部分 (.625):用“乘2取整,顺序排列”法。
- 0.625 × 2 = 1.25 … 取整1 (最高位)
- 0.25 × 2 = 0.5 … 取整0
- 0.5 × 2 = 1.0 … 取整1 (最低位)
- 将整数部分从上往下排列:
.101
- 所以
(0.625)₁₀ = (.101)₂
-
合并结果:
10010.101
答案:(18.625)₁₀ = (10010.101)₂
例题3:八进制 ↔ 二进制 (快捷方法)
题目: 将八进制数 57.24
转换为二进制数。
解答:
八进制和二进制有天然对应关系(1位八进制数对应3位二进制数)。
- 将每位八进制数拆开:
5
,7
,.
,2
,4
- 查阅或计算每位对应的3位二进制数:
- 5 → 101
- 7 → 111
- 2 → 010
- 4 → 100
- 按顺序组合起来:
101111.010100
- 可以省略末尾不必要的0,写成
101111.0101
答案:(57.24)₈ = (101111.0101)₂
逆向练习: 将二进制数 1100101.01101
转换为八进制数。
- 以小数点为中心,向左向右每3位一组,不足的补0。
- 整数部分
1100101
→ 001100
101
(补两个0) - 小数部分
.01101
→.011
010 (补一个0)
- 整数部分
- 将每3位二进制数转换为一位八进制数:
- 001 → 1
- 100 → 4
- 101 → 5
- 011 → 3
- 010 → 2
- 组合结果:
145.32
答案:(1100101.01101)₂ = (145.32)₈
例题4:十六进制 ↔ 十进制 (综合)
题目: 将十六进制数 2A.8
转换为十进制数。
解答:
转换方法与二进制转十进制类似,但基数为16。注意字母 A
表示10。
-
整数部分 (2A):从右向左,每位乘以16的位次幂。
- A(10) × 16⁰ = 10 × 1 = 10
- 2 × 16¹ = 2 × 16 = 32
- 整数部分总和:32 + 10 = 42
-
小数部分 (.8):从左向右,每位乘以16的负位次幂。
- 8 × 16⁻¹ = 8 × (1/16) = 0.5
-
合并结果:42 + 0.5 = 42.5
答案:(2A.8)₁₆ = (42.5)₁₀
例题5:任意进制 → 十进制 (进阶)
题目: 将五进制数 123.4
转换为十进制数。
解答:
方法通用,只需将基数改为5。
-
整数部分 (123)₅:从右向左,每位乘以5的位次幂。
- 3 × 5⁰ = 3 × 1 = 3
- 2 × 5¹ = 2 × 5 = 10
- 1 × 5² = 1 × 25 = 25
- 整数部分总和:25 + 10 + 3 = 38
-
小数部分 (.4)₅:从左向右,每位乘以5的负位次幂。
- 4 × 5⁻¹ = 4 × (1/5) = 0.8
-
合并结果:38 + 0.8 = 38.8
答案:(123.4)₅ = (38.8)₁₀
总结与技巧
转换类型 | 关键方法 | 技巧 |
---|---|---|
N进制 → 十进制 | 按权展开求和 | *①\text{\red{*}{\small{①}}}*①对每一位×N位数×N^{位数}×N位数次方 |
十进制 → N进制 | 整数除N取余,小数乘N取整 | 整数部分倒序,小数部分正序 |
二进制 ↔ 八进制 | 三位一组 | 八进制是二进制的简写形式 |
二进制 ↔ 十六进制 | 四位一组 | 十六进制是二进制的更简形式 |
对*\text{\red{*}}*部分进行解释(即注释)
①如(101)2(101)_2(101)2展开得1×20+0×21+1×22=1+2+4=71×2^0+0×2^1+1×2^2=1+2+4=71×20+0×21+1×22=1+2+4=7
对于N进制转M进制
建议是转为十进制或者二进制再转化
——例题由DeepSeek生成
(奇妙的MarkDownMarkDownMarkDown和符号我也看得迷糊)
总结是自己写的
在C++中的运用
可以用string数组储存,然后逐位提取进行计算,最后再计算为其他进制
即可实现进制转换
给个好玩的思路:可以用二进制做加密器
代码放末尾
例:
#include<bits/stdc++.h>
using namespace std;
int z2_10(string a){//二进制转十进制 int len=a.size();//长度int answer=0;//结果 int b=1;//从最低位开始,权重初始为1for(int i=len-1;i>=0;i--){if(a[i]=='1') {answer+=b;}b*=2;//每向左移动一位,权重乘以2}return answer;
}
int main(){string x;cin>>x;cout <<z2_10(x);return 0;
}
~ 完结撒花完结撒花完结撒花 ~
附:这期没有题单
给的是较为基础的例题
下一篇预告:邻接表/…
加密器实现
我方和对方都要有的程序
#include<bits/stdc++.h>
#include <locale>
using namespace std;
int z2_10(string a){//二进制转十进制 int len=a.size();//长度int answer=0;//结果 int b=1;//从最低位开始,权重初始为1for(int i=len-1;i>=0;i--){if(a[i]=='1') {answer+=b;}b*=2;//每向左移动一位,权重乘以2}return answer;
}
string z10_2(int x){//十进制转二进制if(x==0)return "0";string answer="";//结果while(x>0){int now=x%2;//将余数转换为字符并添加到结果中answer+=(now+'0');// 除以2,继续处理下一位x/=2;}reverse(answer.begin(),answer.end());//反转字符串return answer;
}
string ST(const string&str){string result="";for(unsigned char c:str){result+=z10_2(static_cast<int>(c));result+="|";}if(!result.empty()) {result.pop_back();//移除最后一个分隔符}return result;
}//将字符串转换为UTF-8编码的二进制序列
string TS(const string&Str){string result ="";string byte="";for(char c:Str){if(c=='|'){if(!byte.empty()){int d=z2_10(byte);result+=static_cast<char>(d);byte="";}}else{byte+=c;}}if(!byte.empty()){int d=z2_10(byte);result+=static_cast<char>(d);}return result;
}//将二进制序列转换回字符串
int main(){int cse;cout <<"输入1加密,输入2破译\n";cin>>cse;cin.ignore();//清除输入缓冲区 if(cse==1){string x;cin>>x;cout <<ST(x)<<endl;}else if(cse==2){string x,noww="";cin>>x;string y=TS(x);cout <<y<<endl;}return 0;
}//已经是2.0版本,支持使用中文和符号