I am trying to parse a 50 character String object to an integer. I have been trying to scan in a data file containing 100 lines (each with a 50 digit number) and compute the sum of the numbers.
Every time I try to parse the String as an integer the call throws a NumberFormatException.
Here's what I have so far..
{
long totalSum = 0;
ArrayList<Long> list = new ArrayList<Long>();
// Create a new JFileChooser object.
JFileChooser fileChooser = new JFileChooser(
"C:\\Users\\Jon\\workspace\\Project Euler\\src");
// Create an "Open File" Dialog box for
// the user.
fileChooser.showOpenDialog(null);
// Get the file the user selects.
File inputFile = fileChooser.getSelectedFile();
try
{
Scanner in = new Scanner (inputFile);
String nextString = "";
// If the scanner has another token to scan,
// continue with the loop.
while (in.hasNext())
{
// The next string is the next number of characters
// that are not seperated by white space.
nextString = in.next();
try {
ing nextNumber = Integer.parseInt(nextString);
list.add(nextNumber);
} catch (NumberFormatException e) {
System.out.println ("NumberFormatException: " + e.getMessage());
}
}
in.close();
I have tried "trimming" the String object before attempting to parse, but there wasn't anything to trim. There isn't any white space in the lines that I am scanning in.
Here are a few lines of what I am trying to scan in and compute the value of:
37107287533902102798797998220837590246510135740250
46376937677490009712648124896970078050417018260538
74324986199524741059474233309513058123726617309629
I've check the API and searched quite thoroughly through the Stack. Anyone know how to get around this?
Your numbers are much too big to fit into an int, with a range of -2147483648 through 2147483647. They are also much too big to fit into a long, with a range of -9223372036854775808L through 9223372036854775807L. If it won't fit into the range of the datatype, then a NumberFormatException is thrown.
You may want to try parsing the numbers into a double:
double nextNumber = Double.parseDouble(nextString);
but that may lose a bit of precision. A Double has 53 bits of precision, good for about 16 digits. You'll lose precision with a double.
To retain precision, use BigInteger:
BigInteger nextNumber = new BigInteger(nextString);
A BigInteger is arbitrary precision and will not lose any precision. You can use basic arithmetic and comparisons directly between BigIntegers.
Related
I am trying to write a program which converts binary numbers into decimal, however as soon as I have a binary number which is bigger than 10 digits I get a java.lang.numberformatexception error. I was wondering how I should rewrite my code in order to handle binary numbers:
try{
//will throw an exception if the user's input contains a non-Integer
int inputNumber = Integer.parseInt(returnEnterNumber());
//when our user wants to convert from binary to decimal
if(binaryToDecimal.isSelected()){
//checks if number is binary
int checkNumber = inputNumber;
while (checkNumber != 0) {
if (checkNumber % 10 > 1) {
throw new InvalidBinaryException();
}
checkNumber = checkNumber / 10;
}
//converts from binary and outputs result
int n = Integer.parseInt(returnEnterNumber(), 2);
displayConvertedNumber(Integer.toString(n));
}
}
catch(Exception e) {
displayConvertedNumber("WRONG INPUT! - TRY again");
}
Edit: I understand why the code fails, seeing as how it takes the number as a decimal and overflows. I am not sure how to rewrite the code to take the input as a binary straight away.
That's not a valid way to check a binary number. You're converting to an int in base 10, then checking that each of the digits in base 10 is zero or one. The conversion itself will fail on long enough input strings, and if it doesn't the checking will fail as well.
You shouldn't be converting it all all, you should be checking the input string itself.
EDIT Actually you don't have to do anything. Integer.parseInt() will check it for you and throw NumberFormatException if the string isn't a number in the specified radix.
You are parsing your binary digit string as a decimal integer first. If it has more than 10 significant digits then its decimal interpretation is too big to fit in an int, so the decimal conversion fails.
When you are going to parse the digit string as a binary number, simply avoid first parsing it as a decimal one. For instance, most of what you posted could be reduced to this:
int inputNumber = Integer.parseInt(returnEnterNumber(),
binaryToDecimal.isSelected() ? 2 : 10);
Take a look at Integers MAX values:
public class MainClass {
public static void main(String[] arg) {
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
}
}
the output will be:
2147483647
-2147483648
This means that if you have more than 10 digits, you have exceeded the max number for the Integer data type.
Try Using BigInteger on your binary value or consider returning it as String
Here is one line of code that will accomplish what you are looking for
System.out.println(new BigInteger("10101010101010111101010101001101010101010101001010101010101001011101010101010101",2).toString());
I have an issue where i am trying to count the amount of numbers with a decimal point however it is just counting whenever there is an integer even if it is a whole one.
Scanner cd = new Scanner(name); // count double
Scanner cn = new Scanner(name).useDelimiter("[^0-9]+"); // count int
while(cn.hasNextInt()) {
cn.nextInt();
numberOfInts++;
}
while(cd.hasNextDouble()) {
cd.nextDouble();
numberOfDecimals++;
}
so yeah the number of decimals justs counts whenever a integer is scanned, even if it is a whole number, i want it too just count numbers with a decimal point.
I am in fundamentals of programming 1 and my professor has asked us to create a txt file with 10 fractions, create a program that would read the fractions, add them, get the sum, and find the average, and finally export the results to a different txt file.
So far I have found out how to create and write to a file, but reading the fractions in my txt file is proving increasingly difficult. It compiles but keeps reading out that exceptions had to e made whenever it is ran.
import java.io.*;
import java.util.Scanner;
public class FahrDylanFileInputOutput {
public static void main(String[] args) throws IOException {
double sum = 0.0;
File input = new File("dylfahrinput.txt");
Scanner inputFile = new Scanner(input);
while (inputFile.hasNext()) {
String line = inputFile.nextLine();
double fraction = Double.parseDouble(line);
sum = sum + fraction;
}
double avg = sum / 10;
inputFile.close();
PrintWriter pw = new PrintWriter("dylfahroutput.txt");
pw.println("Sum is : " + sum + "\n Average is: " + avg);
// add this to the end of the overall program.
pw.close();
System.out.println("Data has been written to the txt file.");
}
}
What could I be doing wrong?
The fractions are 1/10 - 9/10
Update: here is the complete code now, still same command prompt message:
public static void main(String[] args) throws IOException {
double numsum = 0.0;
double densum = 0.0;
File input = new File("dylfahrinput.txt");
Scanner inputFile = new Scanner(input);
while (inputFile.hasNext()) {
String line = inputFile.nextLine();
String[] fract = line.split("/");
int num = Integer.valueOf(fract[0]);
int den = Integer.valueOf(fract[1]);
double fraction = num / den;
numsum = (numsum + num);
densum = den;
}
double avg = numsum / 10;
inputFile.close();
PrintWriter pw = new PrintWriter("dylfahroutput.txt");
pw.println("Sum is : " + numsum + "/" + densum + "\n Average is: " + avg);
// add this to the end of the overall program.
pw.close();
System.out.println("Data has been written to the txt file.");
}
First of all, it looks like you're mostly on the right track, at least as far as reading the file, having a variable store the sum of the fractions you've read, etc.
Presumably line will contain string values like "1/10" or "6/10" as you iterate through the lines of the file.
I recommend checking the documentation for Double.parseDouble(String), because it's expecting a decimal-formatted number.
So, you're going to have to parse the string yourself. How would you do that?
You have two integers separated by a '/' character. How can you get the integers by themselves?
Try String.split()
new String("I love pizza").split(" ") will give you ["I", "love", "pizza"].
new String("243/19").split("/") will give you ["243","19"].
Now, let's assume you have a couple of integers, representing the numerator and the denominator. You have a number of options in terms of how to deal with them.
The simplest would be to just add the numerators together and ignore the denominator.
If you have one fraction per line, e.g. your file is
1/10
9/10
Then you have to replace the line :
double fraction = Double.parseDouble(line);
By
String[] fract = line.split("/");
int num = Integer.valueOf(fract[0]);
int den = Integer.valueOf(fract[1]);
double fraction = (double)num / den;
Double.parseDouble() doesn't handle strings representing fractions, like "1/10", only strings representing decimal numbers, like "0.1".
I am guessing you want to have a program read the file, parse the file, do the math, then output to a new file?
First off computer do not think in fractions, it is all 0's or 1's.
What you are going to have to do is create a Fraction Class
Your class should have a Numerator of Int Type, and a Denominator of Int Type.
You are also going to want to have couple of function to change the denominator that in turn changes the Numerator.
You should then have a class that can do the math with 2 fraction classes.
I would also make sure your fraction class has a toString() override as well.
This is if your Professor wants Fractions in the output file.
Also some comments on your code.
If you are inputting from a Text file, and you are dividing by 10... Tisk tisk,
You should be Counting the number of fractions you are finding in the text file.
Just a heads up.
UPDATE
Looking at your current code with denominator sum.... bad bad bad math.
Here is your Fraction Class:
public class Fraction
{
private int numerator;
private int denominator;
private Fraction(){}
public Fraction(int numerator, int denominator)
{
this.numerator = numerator;
this.denominator = denominator;
}
public void multiplyDenominatorByFactor(int x)
{
this.numerator = this.numerator*x;
this.denominator = this.denominator*x;
}
public void simplfy()
{
//... think this one out.
}
public String toString()
{
return ""+this.numerator+"/"+this.denominator+"\n";
}
}
Seeing how this is a class on how to learn programming/java I would also consult your book. I am not going to do your homework for you. Also make sure you do not break the rules of math.
Also if your teacher does not need the results in fractions then you can just convert fraction to doubles or floats by dividing the numerator by the denominator using the split method every one keeps recommending.
If your teacher wants fractions as the returned value, your most accurate results are going to come from keeping your fractions in fraction form. Other wise if accuracy is not required you can convert decimals back into fractions.
Again just think about how you would do it on paper and duplicate that into code. Take a bit of imagination.
This is the actual question:
Write an interactive program that adds two integers of up to 50 digits each
(Represents integer as an array of digits).
This is a homework question and the language to be used is Java. I got this far but I don't think it is even close.
1. It is not taking input more than 20 digits but have to work with 50 digits.
2. The method 'integerToDigits' is producing two arrays but i am unable to sort out how to use them and add them in the main method.
Help please.
package One;
import java.util.Scanner;
public class AddInt {
public static void main(String[] args) {
Long x,y;
Long a[] = new Long[50];
Long b[] = new Long[50];
System.out.println("Please enter two numbers which have no more than 50 digits: ");
Scanner s = new Scanner(System.in);
x = s.nextLong();
y = s.nextLong();
System.out.println(x+ "and "+y);
integerToDigits(x);
integerToDigits(y);
}
public static Long[] integerToDigits(Long n){
Long digits[] = new Long[50];
Long temp = n;
for(int i = 0; i < 50; i++){
digits[49-i] = temp % 10;
temp /= 10;
}
return digits;
}
}
It is not taking input more than 20 digits but have to work with 50 digits.
This is because you're using x = s.nextLong() which is trying to convert the input to a long. The maximum long value is 9223372036854775807 which is nowhere near 50 digits. You'll need to get the input as a String and then covert that to your int[]
The method 'integerToDigits' is producing two arrays, but I am unable to sort out how to use them and add them in the main method.
In terms of adding up the arrays of digits, you can use the same process we learn very early on in school.
Add the units, then carry over any tens.
Add the tens and carry over any hundreds.
Add the hundreds and carry over any thousands.
...
This process can be iterated adding each order of magnitude with the carry over from the previous one.
Hopefully those tips give you a way to solve your problem.
If you do want a solution, I've produced one here that seems to work as you require. (Although not in ideone apparently)
If "Represents integer as an array of digits" is a suggestion and not a requirement a solution using BigInteger would look something like:
// read numbers from input
// store first value as String "firstNumber"
// store second value as String "secondNumber"
BigInteger a = new BigInteger(firstNumber);
BigInteger b = new BigInteger(secondNumber);
BigInteger result = a.add(b);
System.out.println("Result is " + result.toString());
If "Represents integer as an array of digits" is a requirement, well, then it's a silly assignment :) No one would store an integer like that. Worst case, I'd store it as a String if BigInteger was not allowed.
I am wanting to store an integer named Amount, I want it to be stored in pence so if the user entered 11.45 it would be stored as 1145. What is the best way to remove the decimal point? Should I be using decimalFormatting in Java?
Edit:
It is entered in string format, was going to covert it to an int. I will give one of your solutions ago and let you know if it works but not sure which one would be the best.. Thanks everyone.
times it by 100 and cast as int. Use decimal formatting is double / float are too inaccurate which they may be for money
If the user input is in the form of a string (and the format has been verified), then you can strip out the decimal point and interpret the result as an integer (or leave it as a string without the decimal point).
String input = "11.45";
String stripped = input.replace(".", ""); // becomes "1145"
int value = Integer.parseInt(stripped);
If it's a float already, then just multiply by 100 and cast, as #user1281385 suggests.
What about convert to float, multiply by 100 and then convert to int?
String pound = "10.45"; // user-entered string
int pence = (int)Math.round(Float.parseFloat(pound) * 100);
This might be also useful: Best way to parseDouble with comma as decimal separator?
Tested and works. Even if the user enters a number without a decimal, it will keep it as such.
double x = 11.45; // number inputted
String s = String.valueOf(x); // String value of the number inputted
int index = s.indexOf("."); // find where the decimal is located
int amount = (int)x; // intialize it to be the number inputted, in case its an int
if (amount != x) // if the number inputted isn't an int (contains decimal)
// multiply it by 10 ^ (the number of digits after the decimal place)
amount = (int)(x * Math.pow(10,(s.length() - 1 - index)));
System.out.print(amount); // output is 1145
// if x was 11.4500, the output is 1145 as well
// if x was 114500, the output is 114500