进制转化

· · 算法·理论

进制是一种计数制,不同的进制间可以互相转换。

K进制的意思就是“逢K进一”,比如现在我们常用的进制就是十进制,计算时逢10进位。

K进制拥有K个符号(0 ~ K-1)。比如十进制里是0 ~ 9,而不是1 ~ 10。

K进制转十进制方法(整数)

Question:这里有一个二进制数 1011 0110,将其转化为十进制数。

计算步骤:

将K进制转十进制时,先从最低位算起。

从右往左计算,取每一位的值,将其乘以自己的位权,再将所有答案相加。

位权即每一位先从最右边的“0”开始,乘以 2 的 n 次方,n 为数字的位置,最低位是 0 ,从左数依次加一。

那么,二进制数“1011 0110”转化为十进制便是:

二进制位 1 0 1 1 0 1 1 0
位权 2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0
相乘结果 128 0 32 16 0 4 2 0

将结果相加:(注:“D”表示结果为十进制)

128+0+32+16+0+4+2+0=182(D)

上面的算式整合成一个直观的式子便是:

(0*2^0)+(1*2^1)+(1*2^2)+(0*2^3)+(1*2^4)+(1*2^5)+(0*2^6)+(1*2^7)=182

2.再举例

再举例。

Question:八进制数 7143 转换成十进制数是多少?

这里的位权就不同了,不是 2^n ,而是 8^n由此可见的,位权是K^n ,其中 K 为进制,n 为位数。

列表计算:

进制位 7 1 4 3
位权 8^3 8^2 8^1 8^0
相乘结果 3584 64 32 3

答案相加:

(3*8^0)+(4*8^1)+(1*8^2)+(7*8^3)=3683

3.字母表示

当一个 K 进制数的某一位大于9(即是一个两位数)时,无法用自然数表示,就会用字母代替。(通常是大写字母)

比如说 16 进制数 AB 就是 10 进制内的 171(计算过程略)。

A 代表 10 进制内的 10,B 代表 11,以此类推,这里不再赘述。

10进制转K进制方法(整数)

Question:十进制数 20 用 二进制 表示是多少?

短除法

将 20 用短除法不断除以 2 ,并且保留得到的余数,将余数倒序记录下来。

20 / 2 = 10 ... 0 10 / 2 = 5 ... 0 5 / 2 = 2 ... 1 2 / 2 = 1 ... 0

得 10100。这里特殊的是,最后一个算式的商也要算进得数。

再举例

再举例。

Question:十进制数 250 用八进制数表示是什么?

根据上文,将十进制数转化为二进制的方法是除以二。不妨猜出,转化成八进制就是不断除以8。将十进制数转化为K进制,就是不断除以K,取余数,最后倒序记录余数。

计算过程如下:

250/8=31...2 31/8=3...7 3/8=0...3

开头的0省去,最终答案得 372 。

(注:由于不方便写短除过程,建议手推一遍,会比较清晰)

K进制转十进制方法(小数)

Question:二进制数 10.01 转十进制是多少?

位权相乘法

首先,先将 10.01 的整数和小数部分分开,得到 10 和 0.01。

先计算 10 转化为十进制数是 (0*2^0)+(1*2^1)=2 ,然后使用类似的方法计算小数部分。

小数部分的计算也是将每一位上的数字乘以对应的位权,十分位的位权是 K^{-1} (K代表进制),百分位的位权是 K^{-2} ,……依次类推。

那么我们轻松地可以得到:

二进制位 0 1
位权 2^ {-1} 2^ {-2}
相乘结果 0 0.25

然后计算小数部分代表的数值:

(0*2^{-1})+(0*2^{-2})=0+0.25=0.25

最后,我们将小数部分和整数部分代表的数值相加:

2+0.25=2.25

由此得到,二进制数 10.01 用十进制表示为 2.25 。

再举例

Question:十六进制数 EA.26 用十进制如何表示?

分离小数部分和整数部分,分别是“EA”和“0.26”。

先计算整数部分:(10(A)*16^0)+(14(E)*16^1)=10+224=234

然后计算小数部分:(2*16^{-1})+(2*16^{-2})=0.125+0.0234375=0.1484375

最后将小数代表的值和整数代表的值相加:234+0.1484375=234.1484375

得到十六进制数 EA.26 转化为十进制数是 234.1484375

这里需要注意,在计算十六进制数的转化的时候,可能会遇到含有字母的情况,即上文“字母表示”中所述。在这道题里,先将“EA”分别转化为“14”和“10”,再进行计算,这样的计算方式更便捷一点。

十进制转K进制方法(小数)

乘K取整法

Question:十进制小数 21.625 用二进制如何表示?

同样如转化十进制一样,我们先把整数部分和小数部分分开计算,得到两个部分:“21”和“0.625”。

计算整数部分用二进制的表示:(过程繁琐,略过)10101

小数部分要一直将其乘 2 ,直到乘积为 1.0 而止。计算过程如下:

计算步骤 乘法公式 乘积 整数部分 剩余小数
第1步 0.625 × 2 1.25 1 0.25
第2步 0.25 × 2 0.5 0 0.5
第3步 0.5 × 2 1.0 1 0.0

然后(不是逆序)顺序记录它们:101

将整数部分与小数部分组合得:10101.101

再举例

再举例。

Question:将十进制小数 0.78125 转换为八进制是多少?

计算小数部分:

计算步骤 乘法公式 乘积 整数部分 剩余小数
第1步 0.78125 × 8 6.25 6 0.25
第2步 0.25 × 8 2.0 2 0.0

顺序组合,最终答案得:0.62

参考代码

输入:第一行两个正整数 NM,第二行一个 N 进制数 x

输出:在 M 进制下的 x

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;

// 字符转数值
int charToInt(char c) {
    if (c >= '0' && c <= '9') return c - '0';
    if (c >= 'A' && c <= 'Z') return c - 'A' + 10;
    return c - 'a' + 10;  // 小写字母
}

// 数值转字符
char intToChar(int x) {
    if (x < 10) return '0' + x;
    return 'A' + (x - 10);
}

int main() {
    int N, M;
    string s;
    cin >> N >> M >> s;

    // 1. N进制转十进制(使用long long防止溢出)
    long long dec = 0;
    for (char c : s) {
        dec = dec * N + charToInt(c);
    }

    // 2. 十进制转M进制
    if (dec == 0) {
        cout << "0" << endl;
        return 0;
    }

    string result;
    while (dec > 0) {
        result.push_back(intToChar(dec % M));
        dec /= M;
    }
    reverse(result.begin(), result.end());

    cout << result << endl;

    return 0;
}

涉及到的数学知识

整数的负数次方

计算公式:

a^{-n} = \frac{1}{a^n} \quad (a \neq 0, n > 0)

例子:

2^{-1}=\frac{1}{2^{1}}=\frac{1}{2}=0.5

一个数的0次方为1

对于任意一个数,其 0 次方的值为 1(而不是 0 )。

例子:

3^0=5^0=32^0=1

题目推荐

推荐洛谷上适合练习的题目(顺序与题目难度无关):

P1143 进制转换

P2084 进制转换

B2143 进制转换

B3869 [GESP202309 四级] 进制转换

(或者点我)

学习资料

from:oi-wiki

oi-wiki--《进位制》

完成时间:2025/8/16 16:52

字数:约 4000 字