如何将此方法更改为 return 字符串列表而不是字符串?

How can this method be changed to return a List of Strings rather than a String?

最近我开始在 Java 中通过包装器(来自此 Github 存储库)使用 GMP 进行一些涉及极值的计算。
'extreme',我指的是有时超过 7 亿位的数字。

一切都工作得很好,但我计划进行的一次计算估计会产生一个大约 80 亿位的数字,尽管 GMP 库可以处理这个问题并且执行代码的机器已经足够了内存,问题是在基数 10 中获取此数字的唯一方法是通过方法 toString(int base)(或简称 toString()),其中 return 是一个包含指定基数的字符串,但是由于 String 依赖于 char 数组来保存字母,如果我没记错的话,它无法容纳 80 亿个字母,因为最大数组大小约为 2^32-6

不幸的是 Java 我不太了解任何其他语言...

因此我的问题是,如何更改 GMP 包装器(可能还有本机代码)以便 return 一个 List<String> 而不是一个带有数字的 String? 如果这太难甚至不可能,我在 Java 中是否还有其他选择来处理这么大的数字?

谢谢!

编辑:我认为 GMP 对象不支持这些简单的按位运算符,但我看到它们有适当的方法。这就是逻辑;您必须将其转换为您的图书馆

使用按位运算符将您的大数字分割成更小的位块,以便 Java 可以消化。然后,将它们分别转换为字符串。 第一个块:(你需要定义 MAX_STRING_SIZE

MAX_STRING_SIZE & largeNumber

第二块:

MAX_STRING_SIZE & (largeNumber >> numbBits(MAX_STRING_SIZE))  // shift right by number of (used) bits in MAX_STRING_SIZE, so it will be aligned for this calculation

第三块:

MAX_STRING_SIZE & (largeNumber >> 2*numbBits(MAX_STRING_SIZE))  // shift twice

此模式可以类似地压缩成 for 循环(以及转换为字符串):

ArrayList<String> strings = new ArrayList<String>();
while (largeNumber > MAX_STRING_SIZE) {
    largeNumber = largeNumber >> numbBits(MAX_STRING_SIZE))  // shift again
    strings.add(Integer.toString(MAX_STRING_SIZE & largeNumber));  // this value will be an integer
}

numbBitsthis answer 中定义(为清楚起见,我将其重命名):

int numbBits(int value) {
    return Integer.SIZE-Integer.numberOfLeadingZeros(value);
}

我不知道数字的类型,所以假设是 BigInteger。试试这个。

更新:创建了变量 DIGITS_PER_STRNG,因此您可以控制每个 String 项的位数。

class Sample {

    private static void test_num_to_string() {
        List<String> list = intToStringList(sampleBigInt());
    }

    private static final int DIGITS_PER_STRNG = 10; // DIGITS_PER_STRNG < Integer.MAX_VALUE ( = max String length)
    private static final BigInteger DIVIDER = BigInteger.valueOf(10);

    private static List<String> intToStringList(BigInteger i) {
        List list = new ArrayList();

        while (i.compareTo(BigInteger.ZERO) > 0) {
            String str = "";
            for (int j = 0; j < DIGITS_PER_STRNG; j ++) {
                BigInteger[] divideAndRemainder = i.divideAndRemainder(DIVIDER);
                str = str + String.valueOf(divideAndRemainder[1]);
                i = divideAndRemainder[0];
            }
            list.add(str);
            System.out.println(str);
        }

        return list;
    }

    private static BigInteger sampleBigInt() {
        BigInteger bigInt = BigInteger.valueOf((int) Math.pow(2, 10000));
        int i;
        for (i = 0; i < 10; i ++) {
            bigInt = bigInt.multiply(bigInt);
        }
        return bigInt;
    }
}