1. 概述

在这个教程中,我们将探讨如何在Java中将一个数字从一种基数转换为另一种。我们将介绍两种方法,用于将数字从二进制(如2)转换为五进制,反之亦然。

2. Integer

java.lang 包含了一个名为 Integer 的类,它是一个包装类,将原始类型 int 转换为 Integer 对象。这个类提供了操作 int 和将 int 转换为 String 对象以及 String 转换为 int 类型的方法。**parseInt()toString() 方法将帮助我们进行基数之间的数字转换**。

2.1. parseInt() 方法

parseInt() 方法有两个参数:String 类型的 sint 类型的 radix:

public static int parseInt(String s, int radix)

它返回第二个参数指定的基数(作为字符串参数的第二个参数)中给定字符串参数的整数值。字符串参数必须是指定基数的数字。如果字符串不符合要求,它会抛出 NumberFormatException,详细情况参见Java官方文档

2.2. toString() 方法

toString() 方法与前面提到的 parseInt() 方法一起使用,用于在不同基数之间转换数字:

public static String toString(int i, int radix)

根据其签名,它的参数包括一个 int 类型的 i 和一个 int 类型的基数, 方法返回一个表示指定基数(第二个参数)的字符串。如果没有提供第二个参数,则默认使用十进制(基数10)。

3. 使用 Integer 类方法 parseInt()toString() 进行基数转换

正如我们之前暗示的,Java中将一个数字从一种基数转换为另一种有两种方法。第一种也是最简单的方法是使用 Integer 类的 parseInt()toString() 方法来完成从给定基数到目标基数的多次转换。让我们创建一个方法,利用这两个方法进行基数转换:

public static String convertNumberToNewBase(String number, int base, int newBase){
    return Integer.toString(Integer.parseInt(number, base), newBase);
}

我们的方法 convertNumberToNewBase() 接收三个参数:代表特定基数系统(第二个参数类型为 int)中的数字的字符串,以及转换的目标基数,类型为 int。该方法返回一个新基数下的字符串。parseInt() 方法接受字符串参数及其基数,返回一个整数值,然后这个整数值被传递给 toString() 方法,将整数转换为目标基数(其第二个参数)下的字符串。

下面是一个例子:

@Test
void whenConvertingBase10NumberToBase5_ThenResultShouldBeDigitsInBase5() {
    assertEquals(convertNumberToNewBase("89", 10, 5), "324");
}

字符串 "89" 在十进制(基数10)下转换为五进制。我们的方法返回结果字符串 "324",这确实是五进制数字系统中的一个数字。

4. 使用自定义方法进行基数转换

另一种在Java中转换基数的方法是编写自己的自定义方法。该方法应接受三个参数:一个数字字符串、一个指定基数的 int 和另一个表示转换新基数的 int

实现这种转换的一种逻辑方式是创建子方法来处理转换代码的较小部分。我们可以定义一个将任何数字从二进制转换为9和十六进制(基数10)的方法,以及一个将十进制转换为二进制、八进制和十六进制的方法:

public static String convertFromDecimalToBaseX(int num, int newBase) throws IllegalArgumentException {
    if ((newBase < 2 || newBase > 10) && newBase != 16) {
        throw new IllegalArgumentException("New base must be from 2 - 10 or 16");
    }
    String result = "";
    int remainder;
    while (num > 0) {
        remainder = num % newBase;
        if (newBase == 16) {
            if (remainder == 10) {
                result += 'A';
            } else if (remainder == 11) {
                result += 'B';
            } else if (remainder == 12) {
                result += 'C';
            } else if (remainder == 13) {
                result += 'D';
            } else if (remainder == 14) {
                result += 'E';
            } else if (remainder == 15) {
                result += 'F';
            } else {
                result += remainder;
            }
        } else {
            result += remainder;
        }
        num /= newBase;
    }
    return new StringBuffer(result).reverse().toString();
}

convertFromDecimalToBaseX() 方法接受两个参数:一个整数和转换的新基数。通过不断将整数除以新基数并取余数来获取结果。对于十六进制数字,方法还包括一个条件判断。另一个方法用于将任意基数转换为十进制,其中包含一个将十六进制字符转换为十进制值的子方法:

public static int convertFromAnyBaseToDecimal(String num, int base) {
    if (base < 2 || (base > 10 && base != 16)) {
        return -1;
    }
    int val = 0;
    int power = 1;
    for (int i = num.length() - 1; i >= 0; i--) {
        int digit = charToDecimal(num.charAt(i));
        if (digit < 0 || digit >= base) {
            return -1;
        }
        val += digit * power;
        power = power * base;
    }
    return val;
}
public static int charToDecimal(char c) {
    if (c >= '0' && c <= '9') {
        return (int) c - '0';
    } else {
        return (int) c - 'A' + 10;
    }
}

我们将这些方法结合起来,得到一个功能强大的方法,可以将数字从任何基数转换为另一种:

public static String convertNumberToNewBaseCustom(String num, int base, int newBase) {
    int decimalNumber = convertFromAnyBaseToDecimal(num, base);
    String targetBase = "";
    try {
        targetBase = convertFromDecimalToBaseX(decimalNumber, newBase);
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    }
    return  targetBase;
}

让我们测试我们的自定义方法,确认其按预期工作:

@Test
void whenConvertingBase2NumberToBase8_ThenResultShouldBeDigitsInBase8() {
    assertEquals(convertNumberToNewBaseCustom("11001000", 2, 8), "310");
}

当字符串 "11001000" 在二进制下转换为八进制时,方法返回字符串 "310"。

5. 总结

在这篇教程中,我们学习了如何在Java中使用 Integer 类的 toString()parseInt() 方法进行基数转换。我们将这两个方法封装到另一个方法中以提高复用性。此外,我们还进一步编写了自己的自定义方法,先将数字字符串转换为其十进制等效值,然后再转换为其他基数。

本教程的所有代码可以在GitHub上找到。