将非常大的BigIntegers打印到Java

时间:2017-11-17 11:39:01

标签: java size limit biginteger

我试图将非常大的BigInteger打印到.txt文件,但是当数字达到一定大小时,它什么都不打印。代码:

BigInteger bi = new BigInteger("16777216");
int exponent = 1000000;
bi = bi.pow(exponent);

String txtToPrint = bi.toString();
sendToFile(txtToPrint, "output.txt");

private static void sendToFile(String txtToPrint, String fileName) {

        try {

            FileWriter fileWriter = new FileWriter(fileName);
            BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
            bufferedWriter.write(txtToPrint);

            bufferedWriter.close();
        }
        catch(IOException e) {
            System.out.println("Error writing to file '" + fileName + "'");
        }

}

每当指数大于566时,输出文件为空,而不是包含数字。目标是指数为1 000 000,甚至更高。

我认为BigInteger没有大小限制,所以我的问题是:我超出了什么限制,有没有办法解决这个问题?

编辑:当尝试刷新并关闭文件编写器时,我遇到了这个例外:

java.io.IOException: Stream closed
at sun.nio.cs.StreamEncoder.ensureOpen(Unknown Source)
at sun.nio.cs.StreamEncoder.flush(Unknown Source)
at java.io.OutputStreamWriter.flush(Unknown Source)
at PrintInt.main(PrintInt.java:4

编辑:问题只发生在Eclipse中运行程序时,我尝试将其导出到外部jar,一切正常。我正在使用Eclipse Mars.1发行版(4.5.1)和Java jre1.8.0_131和Cp1252编码。

4 个答案:

答案 0 :(得分:2)

我大多在猜这里。我猜这个问题来自BufferWriter

让我们尝试使用更直接的approch Outputstream并尝试使用资源来正确关闭所有内容。

File f = new File(fileName);
try (
        FileOutputStream fos = new FileOutputStream(f);
        OutputStreamWriter os = new OutputStreamWriter(fos);
        Writer out = new BufferedWriter(os) 
){
    out.write(txtToPrint);
} catch(IOException e) {
    System.out.println("Error writing to file '" + fileName + "'");
}

我在过去看到过一些操作系统同步问题,但是文件从未丢失数据,数据只是稍微复制了一下...但为什么不...在write之后,只是等待OS验证数据是在文件中刷新(不在OS缓存中)

out.flush(); //flush the stream
fos.getFD().sync(); //sync with the OS

答案 1 :(得分:1)

在Java 8 中,一些信息被添加到BigInteger javadoc中,给出了最小支持范围和当前实现的实际限制

BigInteger must support values in the range -2Integer.MAX_VALUE (exclusive) to +2Integer.MAX_VALUE (exclusive) and may support values outside of that range.

实施说明:当结果超出支持范围-2Integer.MAX_VALUE(不包括)到+ 2Integer.MAX_VALUE(不包括)时,BigInteger构造函数和操作会抛出ArithmeticException。

答案 2 :(得分:0)

我想说,字符串大小可能是限制。

  

你应该能够获得一个长度为Integer.MAX_VALUE的字符串(Java规范始终为2147483647(231-1),数组的最大大小,String类用于内部存储)或最大堆的一半大小(因为每个字符是两个字节),以较小者为准。

答案 3 :(得分:0)

是的,当我们需要具有任意精度的非常大的数字时使用它。重要的是要注意“任意”精度或数字位数并不意味着“无限制”:它意味着计算中精度数字或位数的位数受内存和/或定义的精度限制的限制我们指定的。