如何更改此方法以返回字符串列表而不是字符串?

时间:2017-08-09 22:05:53

标签: java string tostring gmp

最近我开始在Java中使用GMP通过包装器(来自此Github repo)进行一些涉及极端数字的计算。
在极端情况下,我的意思是有时数字超过700亿的数字。

一切都工作得非常好,但是我计划进行的一个计算估计产生一个大约8个bilion数字的数字,虽然GMP库可以处理它,并且执行代码的机器有足够的内存,问题是在基数10中获取此数字的唯一方法是通过方法toString(int base)(或简称toString())返回包含指定基数的字符串,但由于字符串依赖于一个用于保存字母的char数组,如果我没有弄错的话,它将无法容纳8个字母,因为最大数组大小是2^32-6

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

因此我的问题是,如何更改GMP包装器(以及可能的本机代码)以返回List<String>而不是单个String的数字? 如果这太难了甚至不可能,那么我在Java中还有其他替代方法可以处理那么大的数字吗?

谢谢!

2 个答案:

答案 0 :(得分:1)

我不知道数字的类型,所以假设是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;
    }
}

答案 1 :(得分:0)

编辑:我建立了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
}

this answer中定义的numbBits(为了清晰起见,我将其重命名):

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