如何将此方法更改为 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
}
和 numbBits
如 this 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;
}
}
最近我开始在 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
}
和 numbBits
如 this 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;
}
}