最近我开始在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中还有其他替代方法可以处理那么大的数字吗?
谢谢!
答案 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);
}