进制转换

发布时间:2019-08-06 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了进制转换脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

导言

进制转换是一道经典的题,基本概念不多说,像下面这样

12(10进制) <=> C(16进制) <=> 1100(2进制) <=> 14(8进制)

注意进制不同时,数值还是一样大的。因此C(16进制)只是12(10进制)的另一种表示,而不是另一个数值。其实我的意思是,表示10进制外的其他进制时都应该用字符串

因此一般有两种情况
1. 10进制整数转换为其他进制字符串
2. 其他进制字符串转换为10进制整数

对于10进制整数转换为8进制或16进制字符串时,C和Java里都有偷懒的办法

/* C */
int num = 12;
char oct_str[100];
char hex_str[100];
sPRintf(oct_str, "%o", num); /* oct_str == "14" */
sprintf(hex_str, "%x", num); /* hex_str == "C" */
/* or printf */
// Java
int num = 12;
String octStr = Integer.toOctalString(num); // octStr == "14"
String hexStr = Integer.toHexString(num); // hexStr == "C"

对于其他进制字符串转换为10进制整数,Java已经提供了完美的方法。

// Java
int num = Integer.parseint("C", 16); // num == 12

当然,这并不是我们想要的,我们希望自己实现一个进制转换的函数。

10进制整数转换为其他进制字符串

先举个栗子——我们是怎么把111(10进制)转换为157(8进制)的呢,其实就是一般的除法。
1. 比111小的最大的8的幂次是64
2. 111 / 64 = 1 ... 47
3. 47 / 8 = 5 ... 7
4. 7 / 1 = 7 ... 0
把3次除法的商连起来就是157(8进制)

算法上的思路跟这个完全一样(如果下面这段看着难受请直接看代码)
1. 假设要被转换的10进制数是num,进制是base,转换结果是result
2. 找到比num小的最大的base^n
3. result的第i位为num / base^(n-i)的商
4. num = num % base^(n-i),即余数作为下一轮的被除数
5. i++并回到第3部除非除数等于0

/* C */
char *itos(int num, int base, char *dest)
{
    int i, divisor = 1;
    char *table = "0123456789ABCDEF";
    while (divisor * base <= num) {
        divisor *= base;
    }
    for (i = 0; divisor >= 1; i++, divisor /= base) {
        dest[i] = table[num/divisor];
        num %= divisor;
    }
    dest[i] = 0;
    return dest;
}

等等你说c语言的这个版本有个问题,为什么要传个char *dest进去呢?我该怎么调用呢?
正确的调用姿势是下面这样的,至于为什么,请看我将来要写的一篇文章——C语言中的字符串与指针。

char str[100];
itos(255, 16, str);
printf("%s", str); /* prints "FF" */

Java版本的代码

// Java
public static String itos(int num, int base) {
    int divisor = 1;
    byte[] table = "0123456789ABCDEF".getBytes();
    String result = "";
    while (divisor * base <= num) {
        divisor *= base;
    }
    for (; divisor >= 1; divisor /= base) {
        result += (char) table[num/divisor];
        num %= divisor;
    }
    return result;
}

其他进制字符串转换为10进制整数

这个就比较简单了,用一个表达式就是(假设字符串是a,有n位)

T[n] = a[0]*base^(n-1) + a[1]*base^(n-2) + ... + a[n-2]*base + a[n-1] 

转化成迭代的式子就是

T[0] = 0
T[i+1] = base*T[i] + a[i]

转化成程序就是

/* C */
int stoi(const char *src, int base)
{
    int i, digit, result = 0;
    for (i = 0; i < strlen(src); i++) {
        if (src[i] >= 'a') {
            digit = src[i] - 'a' + 10;
        } else if (src[i] >= 'A') {
            digit = src[i] - 'A' + 10;
        } else {
            digit = src[i] - '0';
        }
        result = base*result + digit;
    }
    return result;
}
// Java
public static int stoi(String src, int base) {
    int digit, result = 0;
    for (int i = 0; i < src.length(); i++) {
        char c = src.charAt(i);
        if (c >= 'a') {
            digit = c - 'a' + 10;
        } else if (c >= 'A') {
            digit = c - 'A' + 10;
        } else {
            digit = c - '0';
        }
        result = base*result + digit;
    }
    return result;
}

脚本宝典总结

以上是脚本宝典为你收集整理的进制转换全部内容,希望文章能够帮你解决进制转换所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。