进制转换(超详细)

时间:2024-11-21 07:53:33

 

一、进制的基础知识

1、什么是进制?

进制也就是进位计数制,是人为定义的带进位的计数方法。对于任何一种进制X进制,就表示每一位置上的数运算时都是逢X进一位。 十进制是逢十进一,十六进制是逢十六进一,二进制就是逢二进一,以此类推,x进制就是逢x进位。

2、生活中常见的进制有哪些?

10进制、60进制、12进制、24进制等;

3、n进制如何数数?

10进制:0 1 2 3 4 5 6 7 8 9 10 11……

2进制:0 1 10 11 100 101 110 111 1000 1001 1010 1011 1100 1101 1110 1111 10000……

8进制:0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 20 21……

16进制:0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20……

二、十进制转换为R进制 

1、十进制整数转换成R进制的整数:  除R取余法 。☆☆☆☆☆

2、学习技巧:可以参照短除法,短除法的作用是用来拆出10进制n的每一位,可以理解为10进制转10进制,使用的方法是除10取余,然后倒过来

那么10进制转R进制,自然就是除R取余,然后倒过来;

 

三、R进制转换为十进制    

1、R进制转10进制整数:   按权展开  

按权展开:基数为N的数字,只要将各位数字与它的权相乘,其积相加,和数就是十进制数。

2、学习技巧: 可以参照10进制整数计算机制来学习 

12345=5 * 1 + 4 * 10 + 3 * 100 + 2 * 1000 + 1 * 10000

     =5 * 100 + 4 * 101 + 3 * 102 + 2 * 103 + 1 * 104

四、10进制和R进制互转程序实现

正整数N转换成一个二进制数

题目描述

输入一个不大于32767的整数n,将它转换成一个二进制数。

输入

输入只有一行,包括一个整数n(0<=n<=32767) 

输出

输出只有一行。

样例

输入

100

输出

1100100

定义字符串存储N转换的二进制数

用短除法除2取余,将余数逆序存入字符串r。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. //10进制转2进制
  4. int n;
  5. string r = "";//存放转换结果
  6. int main(){
  7. cin>>n;
  8. //当n!=0循环
  9. while(n != 0){
  10. //cout<<n%2;//取余
  11. //将n%2的结果转换为字符+到r前面
  12. r = char(n%2+'0') + r;
  13. n=n/2;//除2
  14. }
  15. //特判输入为0的情况
  16. if(r == "") cout<<0;
  17. else cout<<r;
  18. return 0;
  19. }

注意:

强制类型转换

    int y = 97;

    cout<<y<<endl;

    //输出ascii码为y的字母

    cout<<char(y)<<endl;

在进制转换的题目中,一定要特别注意输入为0的情况。

正整数n转换为16进制

题目描述

请从键盘读入一个非负整数 n( n 是一个不超过 18 位的非负整数),将 n 转换为 16 进制!

注意:16 进制即逢 16 进 1,每一位上可以是从小到大为0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F共 16 个大小不同的数,即逢 16 进 1,其中用 A,B,C,D,E,F 这六个字母来分别表示 10,11,12,13,14,15。

如:60 的十六进制为 3C。(字母请用大写

输入

一个不超过 181818 位的非负整数 nnn 。

输出

该数的十六进制值。

样例

输入

100000000000

输出

174876E800

思路:除16取余!

逆序存储到字符串时要注意:

整数0~9,转换为字符’0’~’9’,x + ‘0’

整数10~15,转换为字符’A’~’F’,x + ‘A’ - 10

解法一:分别判断n%16结果在0~9及10~15的哪个范围,分别转换为对应的字符

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. long long n;
  4. string r = "";//存放16进制
  5. int main(){
  6. cin>>n;
  7. //特判输入为0的情况
  8. if(n == 0){
  9. cout<<0;
  10. return 0;//停止函数
  11. }
  12. //短除法
  13. while(n != 0){
  14. //n%16:如果在0~9之间,转换为字符'0'~'9'
  15. //如果在10~15之间,转换为字符'A'~'F'
  16. if(n%16 <= 9){
  17. r = char(n%16+'0') + r;
  18. }else{
  19. r = char(n%16+55) + r;
  20. }
  21. n = n / 16;//除16
  22. }
  23. cout<<r;
  24. return 0;
  25. }

解法二:用字符串存储十六进制对应的字符,简化16进制转为字符的过程

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. long long n;
  4. string r = "";//存放16进制
  5. string t = "0123456789ABCDEF";//存放0~15对应的字符
  6. int main(){
  7. cin>>n;
  8. //特判输入为0的情况
  9. if(n == 0){
  10. cout<<0;
  11. return 0;//停止函数
  12. }
  13. //短除法
  14. while(n != 0){
  15. //n%16:如果在0~9之间,转换为字符'0'~'9'
  16. //如果在10~15之间,转换为字符'A'~'F'
  17. r = t[n%16] + r;
  18. n = n / 16;//除16
  19. }
  20. cout<<r;
  21. return 0;
  22. }

注意:

int最多表达到231-110位整数;

long long最多表达到263-119位整数;

10进制转D进制

题目描述

十进制整数 N 和其他 D(D的值为 2、8、16)进制数的转换是计算机实现计算的基本问题,其解决方法很多,其中一个简单算法就是除 D 取余,然后倒过来得到 D 进制的数。

例如

(1348)10=(10101000100)2
(1348)10=(2504)8
(1000)10=(3E8)16

(请注意:转 16  进制时  用 A 代表余数 10 ,B 代表余数 11 ……)

假设现要编制一个满足下列要求的程序:对于输入的任意一个非负十进制整数(n≤1,000,000,000),打印输出与其等值的 D 进制数。

输入

有两个整数 N 和 D,N 表示要转换的十进制非负整数, D 代表要转换的进制(2、8或16)

输出

N 进制转 D 进制的结果。

样例

输入

1348 2

输出

10101000100
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. string t = "0123456789ABCDEF",r = "";
  4. int n,d;
  5. int main(){
  6. cin>>n>>d;
  7. while(n != 0){
  8. r = t[n%d] + r;
  9. n = n / d;
  10. }
  11. if(r == "") cout<<0;
  12. else cout<<r;
  13. return 0;
  14. }

二进制转换十进制

题目描述

请将一个25位以内的2进制正整数转换为10进制!

输入

一个25位以内的二进制正整数

输出

该数对应的十进制

样例

输入

111111111111111111111111

输出

16777215

1

1

0

1

0

1

2

3

4

5

6

7

8

9

10

11

()-1

思路:从最低位开始(()-1),倒过来计算(按权展开)

s[i] – ‘0’

准备变量t表示2的n次方,t = 1每循环一次,t = t * 2

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. string s;
  4. int t = 1;//表示2的次方,默认是2的0次方
  5. int r = 0;//表示2进制对应的10进制
  6. int main() {
  7. cin>>s;
  8. //倒过来按权展开
  9. for(int i = s.size() - 1;i >= 0;i--){
  10. //s[i] - '0':获得s[i]这个字符对应的整数
  11. r = r + (s[i] - '0') * t;
  12. t = t * 2;
  13. }
  14. cout<<r;
  15. return 0;
  16. }

十六进制转十进制

题目描述

请将一个不超过10位的十六进制正整数转换为十进制整数。

输入

10位以内的十六进制正整数,如果该十六进制中有字母,字母用大写英文字母表示。

输出

该数对应的十进制整数。

样例

输入

2ECF

输出

11983

2

E

C

F

0

1

2

3

4

5

6

7

8

9

10

11

思路:逆序计算,按权展开!

从s中获取每一位s[i]是字符,要转换为实际的整数!

s[i]:’0’~‘9’,s[i] – ‘0’

s[i]:’A’~’F’,s[i] – ‘A’ + 10

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. string s;
  4. long long r = 0,t = 1;//t表示权重(16的次方)
  5. int main() {
  6. cin>>s;
  7. //逆序循环字符串,从最低位开始计算
  8. for(int i = s.size() - 1;i >= 0;i--){
  9. //如果当前位是数字字符 0~9
  10. if(isdigit(s[i])){
  11. r = r + (s[i] - '0') * t;
  12. }else{
  13. //如果是字母 10~15
  14. r = r + (s[i] - 55) * t;
  15. }
  16. //权重提升
  17. t = t * 16;
  18. }
  19. cout<<r;
  20. return 0;
  21. }

小丽找半个回文数

题目描述

小丽同学在编程中学到了回文数的概念,如果一个数正过来读和反过来读是同一个数,那么这个数就是回文数;比如:2、5、8、66、121、686、12321都是回文数,小丽发现,这样的数不算多。于是小丽有个想法,如果这个数不是回文数,但这个数在2进制或者16进制下是回文数,就算这个整数是半个回文数,比如417并不是回文,但417对应的16进制数是1A1是回文数,因此417算半个回文数。
请你编程帮助小丽找符合条件的半个回文数。

输入

第一行是一个整数n(10<=n<=100)
第二行是n个整数(这些整数都是0~10^8之间的整数)

输出

所有符合条件的半个回文数,每行一个。

样例

输入

  1. 5
  2. 121 417 27 100 21

输出

  1. 417
  2. 27
  3. 21
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. /*
  4. 半个回文:数字x在10进制下不是回文,
  5. 在2进制或者16进制下是回文
  6. */
  7. //判断整数n在d进制下是否是回文
  8. bool huiwen(int n,int d){
  9. string r = "",t = "0123456789ABCDEF";
  10. while(n != 0){
  11. r = t[n%d] + r;
  12. n = n / d;
  13. }
  14. //判断r是否是回文
  15. string r2 = r;
  16. reverse(r2.begin(),r2.end());
  17. //cout<<r<<" "<<r2;
  18. if(r == r2){
  19. return true;
  20. }else{
  21. return false;
  22. }
  23. }
  24. int main() {
  25. int n,x;
  26. cin>>n;
  27. for(int i = 1;i <= n;i++){
  28. cin>>x;
  29. if(huiwen(x,10)==false&&(huiwen(x,2)==true||huiwen(x,16))){
  30. cout<<x<<endl;
  31. }
  32. }
  33. return 0;
  34. }