Rudy
Rudy

Reputation: 467

Printing very large BigIntegers to a file in Java

I'm trying to print a very large BigInteger to a .txt file, but when the number reaches a certain size, it prints nothing. Code:

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 + "'");
        }

}

Whenever the exponent is greater than 566 the output file is empty, instead of containing the number. The goal is to have an exponent of 1 000 000, or even greater.

I thought BigInteger did not have a size limit, so my question is: What limit am I exceeding and is there a way to solve this problem?

EDIT: When trying to flush and close the filewriter, I got this exception:

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

EDIT: The problem only occurs when running the program in Eclipse, I tried exporting it to an external jar, and everything worked just fine. I am using Eclipse Mars.1 Release (4.5.1) and Java jre1.8.0_131 and Cp1252 encoding.

Upvotes: 3

Views: 816

Answers (4)

AxelH
AxelH

Reputation: 14572

I am mostly guessing here. I would guess the problem come from the BufferWriter.

Let's try with a more direct approch, Outputstream and try with resource to close everything properly.

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 + "'");
}

I have seen it in the past some OS synchronization issues but the file never loose the data, the data is just copied with a small delayed... but why not ... after the write, just wait for the OS to validate the data is flush in the file (not in the OS cache)

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

Upvotes: 2

SalmaSulthan
SalmaSulthan

Reputation: 61

Yes its used when we need very big numbers with arbitrary precision. It's important to note that "arbitrary" precision or number of digits does not mean "unlimited": it means that the number of digits in a number or number of digits of precision in a calculation is limited by memory and/or defined limits to precision that we specify.

Upvotes: 0

G2M
G2M

Reputation: 68

In Java 8, some information was added to the BigInteger javadoc, giving a minimum supported range and the actual limit of the current implementation:

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

Implementation note: BigInteger constructors and operations throw ArithmeticException when the result is out of the supported range of -2Integer.MAX_VALUE (exclusive) to +2Integer.MAX_VALUE (exclusive).

Upvotes: 1

user8836907
user8836907

Reputation:

I would say, the String size is maybe the limit.

You should be able to get a String of length Integer.MAX_VALUE (always 2147483647 (231 - 1) by the Java specification, the maximum size of an array, which the String class uses for internal storage) or half your maximum heap size (since each character is two bytes), whichever is smaller.

Upvotes: 0

Related Questions