NumberFormatException while converting large textual numbers to BigInteger - java

I have a .dat file that contains lots of huge numbers such as 568e24 1.20536e8 1.3526e12 1.5145e11. And I already input these numbers as String, and stored in ArrayList. I need to use these number to calculate and represent gravitational body in Solar System. But in java it already exceeds the upper limit of Double and Int. What am I suppose to do to use these numbers in Java.
Here is my code that input these data and store these data as String in ArrayList.
public static void main(String[] args) throws Exception{
Scanner input = new Scanner(new File("solarsystem.dat"));
ArrayList<String[]> BodyData = new ArrayList<String[]>();
input.nextLine();
while(input.hasNextLine()){
String x = input.nextLine();
String[] x1 = x.split("[^a-zA-Z0-9().]+");
BodyData.add(x1);
}
System.out.println(BodyData.get(0)[0]);
I am trying to use BigInteger to change String to BigIntiger by following code:
BigInteger reallyBig = new BigInteger("1898e24");
System.out.print(reallyBig);
But the output is wrong:
Exception in thread "main" java.lang.NumberFormatException: For input string: "1898e24"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.math.BigInteger.<init>(BigInteger.java:470)
at java.math.BigInteger.<init>(BigInteger.java:606)
at tryScanner.main(tryScanner.java:18)
So ...now.. what should I do to use this large number such as 1898e24. Do I need to change the format of this number (1898e24), such as 1898000000000...?

You could use something like BigInteger, which should be larger then you need.

Related

How to convert scanner to String or List

I have a scanner with many lines of text(representing number) and I want to convert all the text in the scanner to a List.
Example:
Scanner myScanner = new Scanner(new File("input.txt"));
input.txt:
000110100110
010101110111
111100101011
101101001101
011011111110
011100011001
110010011100
000001011100
101110100110
010001011100
011111001010
100111100101
111111000010
My first thought was to convert it to a String by changing the delimiter to something I know is not in the file:
myScanner.useDelimiter("impossible String");
String content = myScanner.next();
and then use
List<String> fullInput = Arrays.asList(content.split("\n"));
However, it gives me problems later on with parsing the numbers on the scanner. I've tried debugging it but I can't seem to understand the problem. For example, I made it print the String to the console before parsing it. It would print a proper number(asString) and then give me NumberFormatException when it is supposed to parse.
Here's the runnable code:
public static void main(String[] args) throws FileNotFoundException {
Scanner myScanner = new Scanner(new File("input.txt"));
myScanner.useDelimiter("impossible String");
String content = myScanner.next();
List<String> fullInput = Arrays.asList(content.split("\n"));
System.out.println(fullInput.get(1));
System.out.println(Long.parseLong(fullInput.get(1)));
}
This is what I ended up using after the first didn't work:
Scanner myScanner = new Scanner(new File("input.txt"));
List<String> fullInput = new ArrayList<>();
while (sc.hasNextLine())
fullInput.add(myScanner.nextLine());
Do you know what's wrong with the first method or is there a better way to do this?
Because you are parsing a string that represents a number that's beyond the size of an integer.
int values can be between -2,147,483,648 to 2,147,483,647.
fullInput.get(1) gives you 010101110111 which is greater than 2,147,483,647.
You can use long.
long val = Long.parseLong(fullInput.get(1));
If the string represents binary numbers and you want to convert them to int, then you need to provide the base when parsing the string.
int val = Integer.parseInt(fullInput.get(1), 2);
For what you are trying to do here, Scanner is the wrong solution.
If your goal is to simply read the all lines of the file as String[] you can use the Files.readAllLines(Path, Charset) method (javadoc) to do this. You could then wrap that as a List using Arrays.asList(...).
What you are actually doing could work under some circumstances. But one possible problem is that String.split("\n") only works on systems where the line terminator is a single NL character. On Windows, the line terminator is a CR NL sequence. And in that case, String.split("\n") will leave a CR at the end of all but the last string / line. That would be sufficient to cause Long.parseLong(...) to throw a NumberFormatException. (The parseXxx methods do not tolerate extraneous characters such as whitespace in the argument.)
A possible solution to the extraneous whitespace problem is to trim the string; e.g.
System.out.println(Long.parseLong(fullInput.get(1).trim()));
The trim() method (javadoc) returns a string with any leading and/or trailing whitespace removed.
But there is another way to deal with this. If you don't care whether each number in the input file is on a separate line, you could do something like this:
Scanner myScanner = new Scanner(new File("input.txt"));
List<Long> numbers = new ArrayList<>();
while (myScanner.hasNextLong()) {
numbers.append(myScanner.nextLong());
}
Finally, #ChengThao makes a valid point. It looks like these are binary numbers. If they are in fact binary, then it makes more sense to parse them using Long.parseLong(string, radix) with a radix value of 2. However if you parse them as decimal using parseLong (as you are currently doing) the values in your question will fit into a long type.

Parse a string and cast certain elements to int

I was working on a bit of code where you would take an input of 2 numbers, separated by a comma, and then would proceed to do other actions with the numbers.
I was wondering how I would parse the string to take the first number up to the comma, cast it to and int and then proceed to cast the second number to an int.
Here is the code I was working on:
Scanner Scan = new Scanner(System.in);
System.out.print("Enter 2 numbers (num1,num2): ");
//get input
String input = Scan.nextLine();
//parse string up to comma, then cast to an integer
int firstNum = Integer.parseInt(input.substring(0, input.indexOf(',')));
int secondNum = Integer.parseInt(Scan.nextLine());
Scan.close();
System.out.println(firstNum + "\n" + secondNum);
The first number is cast to an integer just fine, I run into issues with the second one.
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
How would I be able to then take the second integer out of the input string and cast it to an Int.
The error mode you're encountering seems reasonable indeed, as you're reading the next line from the scanner and therefore explicitly no longer operating on the first input anymore.
What you're looking for is probably this:
int secondNum = Integer.parseInt(input.substring(input.indexOf(',') + 1));
When defining secondNum, you're setting it equal to the parsed integer of the next line the scanner object reads, but all of the data has already been read. So rather than read from the scanner again, you'll want to call Integer.parseInt on everything after the comma.
It fails because all digit are given by the user on the same line. and you have two Scanner.nextLine(); the second is probably empty.
here is a solution :
Scanner Scan = new Scanner(System.in);
System.out.print("Enter 2 numbers (num1,num2): ");
//get input
String input = Scan.nextLine();
StringTokenizer st = new StringTokenizer(input, ",");
List<Integer> numbers = new ArrayList<>();
while (st.hasMoreElements()) {
numbers.add(Integer.parseInt(st.nextElement()));
}
System.out.println(numbers);
If input on one line, both the numbers will be stored in the String variable input. You don't need to scan another line. It will be empty, and you cannot cast the empty string to an int. Why not just parse the second number out of input, as you did the first.

How to read an integer that starts with zero?

This is a program to read an integer:
public static void main(String argv[]) {
Scanner input = new Scanner(System.in);
int x = input.nextInt();
System.out.println(x);
}
But if I enter an input like this: 000114 it will be read like 114.How to read integer starts with zeroes?
Zeros are ignored at the start of an int. If you need the zeros to be displayed, store the number as a String instead. If you need to use it for calculations later, you can convert it to an int using Integer.parseInt(), so your code should look like this:
String x = input.next();
System.out.println(x);
//if you need x to be an int
int xInt = Integer.parseInt(x);
Keep in mind that, in this example, xInt will lose the zeros.
Perhaps you should read the input as a string and not as an integer if you really need to have the leading zeroes.
That is the expected outcome when reading an int with leading 0s because 000114 isn't an int when represented like that.
If you need it to be 000114 then you should read it as a string.

Reading a multi datatype file into an ArrayList in Java

I am trying to read a file, which the user inputs, and the file has numbers and characters. I only want to store the numbers in an Arraylist but I keep getting stuck, help would be greatly appreciated. This is what I have. Sorry if this has been answered, I am new to the site.
import java.util.*;
import java.io.*;
public class ArrayListClient {
public static final int SIZE = 100;
public static void main(String[] args) throws FileNotFoundException {
String fileName, fileName2;
UnorderedArrayList list1 = new UnorderedArrayList(SIZE);
Scanner input = new Scanner(System.in);
System.out.print("Please input the name of the file to be opened for the first list: ");
fileName = input.nextLine();
System.out.println();
Scanner inputFile = new Scanner(new File(fileName));
int num = inputFile.nextInt();
while(inputFile.hasNextInt()) {
int num2 = inputFile.nextInt();
list1.insertEnd(num);
num = num2;
}
list1.print();
}
}
the input file is 13 c v b 25 34 x x 67 56 10 a a 20 27 2 a s 5 1 45 59
The loop you provided is correct, although you don't need this line outside of the while loop:
int num = inputFile.nextInt();
If the file you provided didn't have a Integer then this would crash your program.
I think you can simply write this and it should work:
while (inputFile.hasNextInt()) {
int num = inputFile.nextInt();
list1.insertEnd(num);
}
The loop checks to see if there is another Integer left in the file (inputFile.hasNextInt()) and then gets it to add to the list (inputFile.nextInt()).
This sounds like it could be a homework question, so I'm hesitant to just give the answer, but if I were you, I would consider writing a filter function (make it a lazy filter if you have to consider files that are very large/won't fit in memory). Your filter function can try Integer.parseInt(yourString); and catch any NumberFormatExceptions that occur because it tried to parse a letter. This approach has the obvious danger of using exceptions to control program flow (normally considered bad practice), but you won't have to traverse the list twice.
Your other obvious option is to write a filter that filters the characters out so that you are only left with number strings, and then just run parseInt over those number strings to turn them into integer values. If performance is a concern, you can avoid double-traversing the list by writing functions that validate a single string value (reject if it's not a number), and then parse it into an int if it is a number, and then add the parsed integers into your array as you go within a foreach loop.
You are most of the way there already since integer detection is built into the Scanner class and the Integer class contains the parseInt() method. Just mutate an array which you define outside of a for each loop and you're good to go.

I got one string consisted of 2 numbers and white space between them, how can I save the numbers in 2 variables? [duplicate]

This question already has answers here:
Take different values from a String and convert them to Double Values
(5 answers)
Closed 8 years ago.
I'm really new to Java programming, so this is a simple question I guess.
I need to write a program that gets as an input the height and weight of a person as one string in which the height and weight separated by white space, for example: 1.68 70
and it calculates and prints the BMI (calculation by the formula weight/height^2).
I read on the internet that getting input from the user can be done by the Scanner class,
and that's what I used. Now I want to save the height and weight in different variables so I can convert them from string to Double, but I don't know how to do it as the whole input is one string . I'm used to Python and slicing :( .. Please help? Thanks a lot.
Based on your comments in the other answer, it looks like you're using a Scanner already. Try something like this.
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter stuff");
double height = scanner.nextDouble();
double weight = scanner.nextDouble();
// do your stuff
}
Here you go.
How to split a String by space
This splits the string into an array on any number of white space. Returns an array of your values. The first value in your string will be in your array at position [0] while the second value at [1].
So to relate that to your example...
String value = "1.68 70";
String[] splitValues = value.split("\\s+");
Double height = Double.parseDouble(splitValues[0]);
Double weight = Double.parseDouble(splitValues[1]);

Categories

Resources