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

Java 如何更改此方法以返回字符串列表而不是字符串?,java,string,tostring,gmp,Java,String,Tostring,Gmp,最近,我开始通过一个包装器(来自此repo)在Java中使用GMP进行一些涉及极端数的计算。 所谓“极端”,我指的是有时超过7亿位数的数字 一切都很好,但我计划进行的一次计算估计产生了一个大约8个十亿位数的数字,尽管GMP库可以处理这个问题,而且执行代码的机器有足够的内存,问题是,以10为基数获取该数字的唯一方法是通过方法toString(int base)(或者简单地说是toString())返回一个包含指定基数的数字的字符串,但由于字符串依赖于char数组来保存字母,如果我没有弄错的话,它将

最近,我开始通过一个包装器(来自此repo)在Java中使用GMP进行一些涉及极端数的计算。
所谓“极端”,我指的是有时超过7亿位数的数字

一切都很好,但我计划进行的一次计算估计产生了一个大约8个十亿位数的数字,尽管GMP库可以处理这个问题,而且执行代码的机器有足够的内存,问题是,以10为基数获取该数字的唯一方法是通过方法
toString(int base)
(或者简单地说是
toString()
)返回一个包含指定基数的数字的字符串,但由于字符串依赖于
char
数组来保存字母,如果我没有弄错的话,它将无法容纳8个十亿个字母,因为最大数组大小在
2^32-6
附近

不幸的是,我不太懂其他语言

因此,我的问题是,如何更改GMP包装(可能还有本机代码),以返回
列表
,而不是带有数字的单个
字符串
? 如果这太难,甚至不可能,我在Java中还有其他方法来处理这么大的数字吗

谢谢大家!

Edit:我联系到GMP对象不支持这些普通的按位运算符,但我发现它们有适当的方法。这就是逻辑;你必须把它转换成你的图书馆

使用逐位运算符将大的数字切碎为Java可以消化的小块。然后,将它们分别转换为字符串。 第一块:(需要定义
最大字符串大小

第二块:

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循环的wise(以及转换为字符串):


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

更新:创建了变量
DIGITS\u PER\u STRNG
,因此您可以控制每个
字符串
项的位数

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;
    }
}
类示例{
私有静态无效测试\u num\u到\u字符串(){
List List=intToStringList(sampleBigInt());
}
私有静态最终整数位数\u PER\u STRNG=10;//位数\u PER\u STRNG0){
字符串str=“”;
对于(int j=0;j
@azurefrog同样的问题,80亿位数无法转换为
字符串。我想知道OP计划如何处理这80亿位数字。在不知道代码现在是什么样子的情况下,回答如何修改某些代码有点困难。@tradeJmark如果您参考我的代码,修改它将无法解决问题,因为障碍是位于我的代码和上面提到的GMP包装之间的字符串。如果可以以某种方式更改此方法,则一切都会好起来。@ElliottFrisch代表我感谢您的澄清!:)@clabe45用于研究。与这个问题有点无关的长篇故事。它必须以10为基数并保存在一个文件中:(谢谢你的回答,但是在处理像上面那样的大数字时,BigInteger还有一些其他的大缺点,我注意到当一个数字乘以大约4亿位数时,另一个大数字(7位数)会带来一些问题)它进入了一个奇怪的死锁状态,所以考虑到这一点和性能,我使用的GMP基本上只是本地代码而不是java代码…虽然你的答案不能解决我的问题,但我认为它应该留在这里,供其他人寻找类似于BigInteger的东西,因为它确实非常有用:-)更新:我意识到我是多么愚蠢,我可以很容易地将这个代码改编成GMP,所以我做到了!谢谢大家,真的很有帮助。产生的字符串是以10为基数向后写的数字,但这很容易修复,只需将其反转即可!现在我的问题是,在转换为字符串的过程中,如何确定用于将数字除以的正确常数?在您的示例中,它是
1000000000
,但我不知道如何优化它:再次感谢您!好的,我编辑了我的帖子。如果您不关心性能,只需调用:<代码> DigsSyPixSype=整数.Max值> /CODE >,但当目标BigInteger足够大时,您可以考虑通过调用:<代码> DigsSyPixSype =整数,Max值/x< /代码>代码>私有静态最终Big整数除法器=BigTigial.ValueOf(10).PoW(x);代码>其中
x
约为10000000或更多。(目标越大,它应该越大。)在我的电脑上,
.pow(100000000)
从未停止过(我的耐心极限是1分钟),供您参考。对不起,我的英语很差。希望它能帮助你啊哈,我明白了,对于其中一个带有
63145508
数字的数字,使用数字
1
后跟500个零,但这需要1小时10分钟。。。对于同一个数字,默认的toString()方法最多需要一分钟:O所以我还在寻找一个可以加快这个过程的数字:(我检查了BigInteger的toString(),但他们正在做一些疯狂的数学,我没有
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
}
int numbBits(int value) {
    return Integer.SIZE-Integer.numberOfLeadingZeros(value);
}
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;
    }
}