首页 文章

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

提问于
浏览
1

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

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

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

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

谢谢!

2 回答

  • 0

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

    编辑:我 Build 了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);
    }
    

相关问题