NumberFormatException when parsing negative integer - java

I am writing a java program to determine if a number is a palindrome.
My code works properly if the argument passed is a positive integer, but throws a NumberFormatException when passing a negative integer.
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.base/java.lang.Integer.parseInt(Integer.java:662)
at java.base/java.lang.Integer.parseInt(Integer.java:770)
at com.stu.Main.isPalindrome(Main.java:28)
at com.stu.Main.main(Main.java:7)
The following solution I took from another stackoverflow thread, which seems to be what the instructor wants us to use, however in the while loop I assume that since a negative number is always less than 0, it will break out of the loop and not calculate the palindrome:
public static int reverse(int number)
{
int result = 0;
int remainder;
while (number > 0)
{
remainder = number % 10;
number = number / 10;
result = result * 10 + remainder;
}
return result;
}
So, I am using strings in my solution below to solve this issue.
Note: we have not yet got to splits and regexps yet.
public class Main {
public static void main(String[] args) {
isPalindrome(-1221); // throws exception
isPalindrome(707); // works as expected - returns true
isPalindrome(11212); // works as expected - returns false
isPalindrome(123321);// works as expected - returns true
}
public static boolean isPalindrome(int number){
if(number < 10 && number > -10) {
return false;
}
String origNumber = String.valueOf(number);
String reverse = "";
while(number > 0) {
reverse += String.valueOf(number % 10);
number /= 10;
}
if(Integer.parseInt(origNumber) == Integer.parseInt(reverse)) {
System.out.println("The original number was " + origNumber + " and the reverse is " + reverse);
System.out.println("Number is a palindrome!");
return true;
}
else
System.out.println("The original number was " + origNumber + " and the reverse is " + reverse);
System.out.println("Sorry, the number is NOT a palindrome!");
return false;
}
}
I am looking for two things here.
First, how do I solve the issue with the negative number in the while loop in the case of the instructors preferred solution?
Second, how can I solve the NumberFormatException in my solution?
Edit: a third question. Why does my solution return false if I never parse back to an int?
if(Integer.parseInt(origNumber) == Integer.parseInt(reverse)) // works
to
if(origNumber == reverse) // does not work
Thanks!

Ok, the easiest way to solve your first and second problem is just to remove the negative sign by using Math.abs(yourNumber) and that's it.
As,
The java.lang.Math.abs() returns the absolute value of a given argument.
If the argument is not negative, the argument is returned.
If the argument is negative, the negation of the argument is returned.
This will solve both of your first and second problem.
Coming to the third one, if you are not converting back to integer you are getting false as to compare string you neet to use equals() method as,
== tests for reference equality (whether they are the same object).
.equals() tests for value equality (whether they are logically "equal").
Hope that helps!! ;)

Related

How To Scan an Integer and Count the Number of '0' Digits? [duplicate]

This question already has answers here:
Java: parse int value from a char
(9 answers)
Closed 2 months ago.
I'm trying to write a small program that will accept an integer input and count the number of even, odd, and zero digits. I can get everything to work except counting how many times 0 occurs in the integer. If I write my conditional statement like:
if(inputString.charAt(index) == '0')
it works. But if I write:
if(test == 0)
It does not work. For some reason I can't query the existence of 0 directly as a number. I have to change it to a string and find it that way. Why can't I just query it directly like in my second example? Seems like it should be pretty straightforward.
import java.util.Scanner;
public class ParseInt {
public static void main(String[] args) {
//Declarations
int index = 0, test, odd = 0, even = 0, zero = 0;
String inputString;
Scanner scan = new Scanner(System.in);
//Inputs
System.out.println("Input an integer");
inputString = scan.nextLine();
//Process
while(index<= inputString.length()-1)
{
test = inputString.charAt(index);
if(inputString.charAt(index) == '0') //this line here
zero++;
if(test%2 == 0)
even++;
if(test%2 != 0)
odd++;
index++;
}
System.out.println("The number of zero digits is " + zero + ".");
System.out.println("The number of even digits is " + even + ".");
System.out.println("The number of odd digits is " + odd + ".");
scan.close();
}
}
I tried changing the line in question to a string and querying that way. It works, but I want to try and query 0 as a number.
The reason why your second attempt is not working is that a char holds a ASCII reference with has it own integer number. If you want to compare a int to char, you have to convert it and then compare, that's why your first attempt work as both is chars.
When you use inputString.charAt(index) java get the ascii code of number 0 (that is 48).
When you compare it with char '0' Java compare ascii code 48 with 48 and it returns true, if you compare it with a integer Java try to do 0==48 and return false
You can examine this site to see every ascii code https://www.ascii-code.com/

Java: Adding and Subtracting Digits Taken from a String

So the purpose of this program is to get the user to enter an integer that the program will recognize as a string. Then the program has to be able to recognize each of the numbers entered and manipulate them as follows. Digits are to be added together if the digits are the same or if the next digit is greater. Digits are to be subtracted if the next digit is smaller.
An example:
The input "234224" should output 13(2+3+4-2+2+4)
However my program gives an output of 17.
I don't know how to fix the problem. My problem is in my first if statement. When the second occurrence of "2" is read I want the program to subtract 2 from the output being calculated but instead it adds 2 because of how I coded the first if statement.
Could someone give me a solution using the same method I used if possible?
public class StringManipulation {
public static void main(String[] args) {
String userInt;
int total = 0;
Scanner input = new Scanner(System.in);
System.out.println("Enter an integer: ");
userInt = input.nextLine();
for (int k = 0; k < userInt.length(); k++) {
int presentNum = userInt.charAt(k);
System.out.println(userInt.charAt(k));
if (presentNum == userInt.charAt(0)) {
presentNum = Character.getNumericValue(presentNum);
total += presentNum;
System.out.println("counter currently at (same)" + total);
} else if (presentNum >= userInt.charAt(k - 1)) {
total += Character.getNumericValue(presentNum);
System.out.println("counter currently at (adding)" + total);
} else if (presentNum < userInt.charAt(k - 1)) {
total -= Character.getNumericValue(presentNum);
System.out.println("counter currently at (subtracting)" + total);
}
}
System.out.println("Output= " + total);
input.close();
}
}
Your problem is with your initial check
if (presentNum == userInt.charAt(0))
in other words, you do stuff if the number you're looking at is the same as the first number. In this particular case, that condition kicks in when you encounter the 2 later in the string, and you end up adding it instead of subtracting it.
You probably wanted that condition to be
if (k == 0)
if (presentNum == userInt.charAt(0)) {
presentNum=Character.getNumericValue(presentNum);
total+=presentNum;
System.out.println("counter currently at (same)" + total);
}
Your problem lies here. The first digit is added to the sum regardless of the previous digit. That means the output changes from 13(2+3+4-2+2+4) to 17(2+3+4 +2 +2+4).
You should have something like
if (k==0){
presentNum=Character.getNumericValue(presentNum);
total+=presentNum;
}
for the first digit.
Try to change the first if condition, as follows
if (k==0) {
presentNum = Character.getNumericValue(presentNum);
total += presentNum;
System.out.println("counter currently at (same)" + total);
}
Because, at the first iteration you have only one operand and you don't have take the value at 0th index for the condition, rather than that just see whether is it the first index.

the second condition in the if statment with or operator

I have the following if statment which contains of two conditions with or perator. So in the following code I am getting this error
java.lang.NumberFormatException: For input string: ""
I thought in java the second condition in the if statment is checked if the first condition is not valid.
The compressDuration could be empty or null or blank or a String vlaue like 100.
In the case below the compressDuration is empty also it is blank also the second condition Integer.parseInt(compressDuration.trim()) must not be checked?
How can I write the if statment to conver the 4 cases empty or null or blank or a String vlaue like 100.?
String compressDuration = "";
if(StringUtils.isBlank(compressDuration) || Integer.parseInt(compressDuration.trim())){
System.out.println("The compressDuration has no value or a ");
}else{
}
I thought in java the second condition in the if statment is checked if the first condition is not valid.
I assume you mean not checked if the first condition is false. And that's correct, it isn't. So clearly, StringUtils.isBlank isn't returning false for "" if what's in your question is a valid example of what you're doing.
I suspect, though, that you have a string with whitespace in it, not "". Note that you're using trim when passing to Integer.parseInt, but not when passing to StringUtils.isBlank.
Note that as Eran pointed out, your code doesn't compile; int can't be used with the || operator, but your code has the condition boolean || int, which lends weight to the idea that this code isn't an accurate representation of what you actually have.
But I suspect it's the trim in the one case but not the other which is the problem.
Perhaps:
String compressDuration = /*...get it from wherever...*/;
compressDuration = compressDuration.trim();
int duration;
if (StringUtils.isBlank(compressDuration) || (duration = Integer.parseInt(compressDuration.trim())) < 0) {
System.out.println("The compressDuration has no value or a value less than zero");
} else {
System.out.println("The compressDuration is " + duration);
}
or if you don't like side-effects in if conditions (and there are good reasons to not like them, but I make some exceptions for very simple cases):
String compressDuration = /*...get it from wherever...*/;
compressDuration = compressDuration.trim();
int duration = StringUtils.isBlank(compressDuration) ? -1 : Integer.parseInt(compressDuration.trim();
if (duration < 0) {
System.out.println("The compressDuration has no value or a value less than zero");
} else {
System.out.println("The compressDuration is " + duration);
}
Try isInt method which will return true if it is valid integer.
if(!isInt(compressDuration.trim())) {
System.out.println("The compressDuration has no value or a ");
} else{
}
public boolean isInt(String str) {
try{
int num = Integer.parseInt(str);
// is an integer!
} catch (NumberFormatException e) {
// not an integer!
return false;
}
return true;
}

Code Fails to Return Integer Value From Method (Java/Eclipse)

I have been scouring this site and others for the last two days, and thus am aware of the overwhelming amount of preexisting questions similar to this one. However, having only started programming three or four weeks ago, I am unable to make sense of any of them and their threads. Considering this, I have an issue that to the more experienced likely possesses a painfully basic and straightforward solution.
Using Eclipse, I must create a program which does the following:
Reads in two numbers (integers)
Contains a method that takes the two integers as parameters and returns the larger of the two.
Contains another method that is called from main() takes the larger number returned by the method in (2) as a parameter and returns the last digit.
Prints the two values returned by the methods in (2) and (3).
The code I have created (displayed below) successfully reads in the user input, but fails to print out both the larger integer and the larger integer's last digit. It instead prints out "0". This is what is printed out to the console:
Enter First Integer: (Entered Integer)
Enter Second Integer: (Entered Integer)
Larger Integer: 0
Last Digit: 0
I believe that the code should function correctly, save for the fact that values determined inside the methods are not being returned to the main. No error messages are being displayed by Eclipse, which leads me to believe that the issue lies within my return statements. Any suggestions or solutions are welcomed and desired. Thank you.
import java.util.Scanner;
public class thursdayWork{
//Determines larger integer and returns it.
public static int processAndReturn(int int1, int int2, int answer){
answer = Math.max(int1, int2);
return answer;
}
//Determines last digit of integer and returns it.
public static int processLargerInt(int answer, int lastDigit){
if((answer >= 0) && (answer < 10))lastDigit = (answer % 10);
else if((answer >= 10) && (answer < 100))lastDigit = (answer % 100);
else if((answer >= 100) && (answer < 1000))lastDigit = (answer % 1000);
else if((answer >= 1000) && (answer < 10000))lastDigit = (answer % 10000);
else System.out.print("Pick smaller numbers.");
return lastDigit;
}
//Calls methods and prints returned values.
public static void main(String[] args){
Scanner console = new Scanner(System.in);
int int1;
int int2;
int answer = 0;
int lastDigit = 0;
System.out.print("Enter First Integer: ");
int1 = console.nextInt();
System.out.print("Enter Second Integer: ");
int2 = console.nextInt();
processAndReturn(int1, int2, answer);
System.out.println("Larger Integer: " + answer);
processLargerInt(answer, lastDigit);
System.out.print("Last Digit: " + lastDigit);
}
}
Instead of passing the answer as a param to both the methods, you should have it returned from the method. You should read more about pass by value vs pass by reference.
public static void main(String[] args) {
// Your scanner code here.
int answer = processAndReturn(int1, int2);
System.out.println("Larger Integer: " + answer);
int lastDigit = processLargerInt(answer);
System.out.print("Last Digit: " + lastDigit);
}
public static int processAndReturn(int int1, int int2){
return Math.max(int1, int2);
}
public static int processLargerInt(int answer) {
return answer % 10;
}
Your problem is in how you deal with processAndReturn. Java passes primitives (like int) by value. Meaning that when you give answer to the method processAndReturn it actually hands the method the value of the variable, so any changes you make to it aren't present where you called it from. The way to get around this is by using the return value of processAndReturn
You should modify that line to be something like this:
int answer = processAndReturn(int1, int2);
And you'll need to modify processAndReturn to only take two arguments.
that would look something like this:
static int processAndReturn(int int1, int int2){
return Math.max(int1, int2); //Note: you can just replace a call to this
// With a call to max, meaning it's pointless
}
You'll need to do something similar for processLargerInt as well.
On an unrelated note, this has nothing to do with eclipse. That is your development environment. This has to do with java, so it wouldn't matter what you were developing it in.

How to detect if a number is greater than Long.MAX value

My application will get number as string from end user. If the number is not numeric, i have to throw error message by saying that to provide number. This i can fix by using NumberFormatException. Another scenario is, user entered greater than Long.MAX value. How i can check this case and give error message to the user to enter smaller number than Long.MAX value? I should not use any third party or open source lib to fix this issue. Even if they are providing solution, How they are resolving it?
Use BigInteger to parse user input and compare the result with Long.MAX_VALUE
String userInput = ...;
BigInteger bigInt = new BigInteger(userInput);
if(bigInt.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) {
throw new Exception(userInput + ": value is too large");
}
If the entered number is greater than Long.MAX value, then what will you do next. It will cause an error as you don't know where to store it.
Better way is to check at the time of user input is in range or not. If it is greater than Long.MAX, store it in BigInteger
Use BigInteger and the longValueExact() method, and catch exceptions:
public static void main(String[] args) {
test("123");
test("9223372036854775807"); // Long.MAX_VALUE
test("-9223372036854775808"); // Long.MIN_VALUE
test("9223372036854775808"); // Long.MAX_VALUE + 1
test("-9223372036854775809"); // Long.MIN_VALUE - 1
test("abc");
}
private static void test(String input) {
long longVal;
try {
longVal = new BigInteger(input).longValueExact();
} catch (NumberFormatException e) {
System.out.println("Value is not a valid integer number: " + input);
return;
} catch (ArithmeticException e) {
System.out.println("Value exceeds range of long: " + input);
return;
}
System.out.println("Got valid long value: " + longVal);
}
OUTPUT
Got valid long value: 123
Got valid long value: 9223372036854775807
Got valid long value: -9223372036854775808
Value exceeds range of long: 9223372036854775808
Value exceeds range of long: -9223372036854775809
Value is not a valid integer number: abc
You can access the max value using Long.MAX_VALUE and check the user entered value in if condition.
Here is another solution without using an extra class other than Java core
public static void main(String[] args) {
System.out.println(isLargerThanLONGMAXVALUE("9223372036854775807")); // false
System.out.println(isLargerThanLONGMAXVALUE("9223372036854775806")); // false
System.out.println(isLargerThanLONGMAXVALUE("9223372036854775808")); // true
System.out.println(isLargerThanLONGMAXVALUE("645459223372036854775807")); // true
System.out.println(isLargerThanLONGMAXVALUE("922")); // false
}
public static boolean isLargerThanLONGMAXVALUE (String number) {
String longMax = String.valueOf(Long.MAX_VALUE);
if (number.length() > longMax.length()) return true;
if (number.length() < longMax.length()) return false;
long a, b = 0;
for (int i = 1 ; i < number.length() ; i++){
a = Long.parseLong(number.substring(0, i));
b = Long.parseLong(longMax.substring(0, i));
if (a > b) return true;
}
if (Integer.parseInt(number.substring(number.length()-1, number.length())) >
Integer.parseInt(longMax.substring(number.length()-1, number.length())))
return true;
return false;
}
Treating the string as a BigInteger and doing the comparison is the best way. But here's another just to show that there's usually more than one way to accomplish something:
public boolean isInRange(String number) {
String maxValue = Long.toString(Long.MAX_VALUE);
number = number.replaceFirst("^0+", ""); // remove leading zeroes
return number.length() < maxValue.length() ||
(number.length() == maxValue.length() &&
number.compareTo(maxValue) <= 0);
}
This assumes that number is composed entirely of digits (no negative sign).
try{
val n = input.toLong()
}catch(e: Exception){
// invalid Long
}

Categories