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
}
Related
I need to make a program that reads hours in this format (934:9h34) or 1835 (18h35). How can I make my program print an error if somebody writes 966 (the 2 last digits over 59? (66>59)
Given a String str:
String str = getTheString();
String lastTwoDigits = str.length() > 2 ? str.substring(str.length() - 2) : str;
int result = 0;
try {
result = Integer.parseInt(lastTwoDigits);
} catch (NumberFormatException e) {
System.err.println("Cannot parse string!");
System.exit(1);
}
if (result > 59) {
System.err.println("Number was over 59!");
System.exit(1);
}
By the way, System.err.println() just prints to standard error rather than standard output, and exit(1) exits the program with a failing error code.
Hope this helps!
This solution will parse the string first, then get the last two digits of the number through result % 100.
private static void timeFormat(String text) {
int result = 0;
if (text.length() < 2) {
System.err.println("String was too short");
return;
}
try {
result = Integer.parseInt(text);
} catch (NumberFormatException e) {
System.err.println("Failed to parse string");
}
if (result % 100 > 59) {
System.err.println("Number was over 59");
}
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
timeFormat(scan.nextLine());
scan.close();
}
Since the title asks "How to evaluate the 2 last digit of a Int?", we can assume that you already have the value in an int variable.
To examine the last 2 digits, calculate the remainder when dividing by 100, i.e. use the % remainder operator:
int value = /*assigned elsewhere*/;
int lastTwoDigits = value % 100;
if (lastTwoDigits > 59) {
System.out.println("ERROR: Invalid value: " + value);
// value is invalid
}
Of course, you should probably also validate that value is not negative.
If, however, a value of -934 is valid, and -966 is not, just eliminate the sign by calling Math.abs():
int lastTwoDigits = Math.abs(value) % 100;
if (lastTwoDigits > 59) {
System.out.println("ERROR: Invalid value: " + value);
// value is invalid
}
This will work. Ensures that last 2 digits are <= 59.
String[] test = { "934:9h34", "1835", "1994", "iwiwiwiw45", "18h45"
};
// match 2 digits at end of string
Pattern p = Pattern.compile("(\\d\\d)$");
for (String t : test) {
Matcher m = p.matcher(t);
if (m.find()) {
// valid integer so convert and compare
if (Integer.valueOf(m.group(1)) <= 59) {
System.out.println("Passes test: " + t);
continue;
}
}
System.out.println("Fails test: " + t);
}
Learn more about Java and regular expressions
here.
First convert user given input into String
String hourInString = Integer.toString(userInput);
Then check if the input is valid or not. Minimum length of the input should be at least 3.
if (hourInString.length() < 3) {
System.out.println("invalid input");
System.exit(1);
}
Then retrieve the last two digit using substring
String lastTwoDigit = hourInString.substring(hourInString.length() - 2,
hourInString.length());
Finally you can validate the number-
if (Integer.parseInt(lastTwoDigit) > 59) {
System.out.println("Error");
}
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!! ;)
My program is supposed to check if an integer is in a random integer. It will return true or false. For example: 45903 contains 4: true. For some reason; my code kept running after i entered the digit. Some thing is wrong with my containDigit() method but i can't seem to figure out. i'm very new to boolean.
import java.util.Scanner;
import java.util.*;
public class checkNum {
public static void main(String[] args) {
// Create a new Scanner object
Scanner console = new Scanner(System.in);
// Create a new Random objects
Random rand = new Random();
// Declare a integer value that is getting the value in the range of[10000, 99999]
int randomNum = rand.nextInt(90000)+10000;
// Show the random value to user by using of System.out.println
System.out.println(randomNum);
// Type a prompt message as "Enter a digit"
System.out.println("Enter a digit: ");
// Assign user input to integer value
int digit = console.nextInt();
// Define a boolean value that is assigned by calling the method "containDigit(12345,5)"
// Show the output
System.out.println(randomNum+ " contains" +
digit+" " + containDigit(randomNum,digit));
}
public static boolean containDigit(int first, int second) {
int digi = 10000;
// Define all statements to check digits of "first"
while (first > 0) {
digi = first % 10;
digi = first / 10;
}
if (digi == second){
return true;
}else {
return false;
}
// If it has "second" value in these digits, return true,
// If not, return false
// return a boolean value such as "return false";
return false;
}
}
If you're not restricted with way of solution, I can suggest below:
return (randomInt + "").contains(digit + "");
I dont understand why are you assigning first %10to digi and then immediately overwriting digi with first / 10.
Your while loop may never exit as first might always be greater than 0. It might never be entered as first might be equal to 0. You might want to do this:
while (first/10 == 0) {
first = first % 10;
if (first == second)
return true;
}
if(first%10 == second)
return true;
return false;
Your while loop never exits:
while (first > 0) {
digi = first % 10;
first = first / 10; // i believe this should be first instead of digit
}
You should add a simple print statement to check what your digit and first variables' values are:
System.out.println("digi: "+digi);
System.out.println("first: "+first);
I have to use different methods for this code, no java shortcuts!
Here is my code:
import java.io.*;
import java.util.Scanner;
public class pg3a {
public static void main(String[] args) throws IOException {
Scanner keyboard = new Scanner(System.in);
String hex;
char choice = 'y';
boolean isValid = false;
do {
switch (choice) {
case 'y':
System.out.print("Do you want to enter a hexadecimal number? ");
System.out.print("y or n?: ");
choice = keyboard.next().charAt(0);
System.out.print("Enter a hexadecimal number: #");
hex = keyboard.next();
hex = hex.toUpperCase();
int hexLength = hex.length();
isValid = valid(hex);
if (isValid) {
System.out.println(hex + " is valid and equal to" + convert(hex));
}
else {
System.out.println(hex + " is invalid.");
}
case 'n':
System.out.println("quit");
}
}while (choice != 'n');
}
public static boolean valid (String validString) {
int a = 0;
if (validString.charAt(0) == '-') {
a = 1;
}
for (int i=a; i< validString.length(); i++) {
if (!((validString.charAt(i) >= 'a' && validString.charAt(i) <= 'f')|| (validString.charAt(i) >= 0 && validString.charAt(i) <= 9)))
{
return false;
}
}
return true;
}
How can I make it so that after the program checks all the parameters for the hexadecimal number and calculates what it should be in decimal form, it prints out that the hexadecimal number is valid and then what the decimal number is??
Also how can I make it a loop that ends with either ^z or ^d to end the program?
To convert Strings representing hexadecimal numbers to Integer, you can use the Integer.toString(String, int); method:
Integer parsedValue = Integer.parseInt(hex, 16);
The first argument is the string to be converted, the second is the radix specification, hence is this value 16 for now.
To be complete, the Integer.toString(Integer, int) is the reverse if the above: it converts an Integer value to a string in the specified radix.
Just create a method named convert, and make it return this.
Printing an Integer is not a big issue, you can just concatenate it to any String using the + operator.
System.out.println("The value: " + parsedValue);
Also, keep in mind, that you have a little problem:
This line makes all the charachters uppercase in your string:
hex = hex.toUpperCase();
But here you check for lowercase letters:
if (!((validString.charAt(i) >= 'a' && validString.charAt(i) <= 'f')|| (validString.charAt(i) >= 0 && validString.charAt(i) <= 9)))
Either do hex=hex.toLowerCase();, or adjust the above condition to check to be between 'A' and 'F'.
Have to mention though that checking the validity of a String ot be converted to a numeric value is different: it tinvolves a try-catch block: try to convert the number, and if it fails, it is not valid...
Integer value; //have to declare it here to be able to access it outside of the try block
try {
value = Integer.parseInt(hex,16);
} catch(NumberFormatException e) {
//if you want to get the stack trace
e.printStackTrace(); //if not using a proper logging framework!!! Don't just print it!
//handle the situation: e.g. break loop, write eror message, offer retry for user, etc...
}
The program is designed for the user to enter a series of numbers until the user enters the sentinel which i set to the value of 0. After the user enters the sentinel the program is supposed to print the highest number and the second highest number in that list. The trouble I'm having is where I expect the second highest number to be it prints 0 instead.
Is there a more elegant way of solving this problem by using the ?: operator? Is it possible?
import acm.program.*;
public class LargestAndSecondLargest extends ConsoleProgram {
public void run() {
int a = 0;
int b = 0;
while (true) {
int value = readInt(" ?: ");
if (value == SENTINEL) break;
if (value > a) {
a = value;
}
else if (value > b) {
b = value;
}
}
println("the largest value is " + a);
println("the second largest number is" + b);
}
private static final int SENTINEL = 0;
}
There are two issues:
The second comparison is wrong.
When you encounter a new highest number, you need to shift the previous highest number into the second-highest slot. Otherwise the sequence 1, 2, 3 would produce 3 and 1 as the two highest numbers.
else if ( b > value )
The above else if condition should be: -
else if ( value > b )
Else, your b will never get changed, if you are entering only positive numbers, and hence the 2nd largest value will be 0.
Also see 2nd requirement in #NPE's answer that is necessarily required.
insert the values into an array. Sort the array then assign the top two values from the array into your output. if only one value is given depending on requirements set them both to the same value or one to 0.
Here my solution (that you can adapt with your superclass):
public class LargeAndSecondLargest {
public static void main(String[] args) {
new LargeAndSecondLargest().run("1 2 2");
}
public void run(String input) {
final int SENTINEL = 0;
int currVal;
Scanner scanner = new Scanner(input);
List<Integer> numbers = new ArrayList<>();
while (scanner.hasNextInt() && ((currVal = scanner.nextInt()) != SENTINEL)) {
numbers.add(currVal);
}
printFirstAndSecondLargest(numbers);
}
private void printFirstAndSecondLargest(List<Integer> numbers) {
Collections.sort(numbers, Collections.reverseOrder());
System.out.println("the largest value is " + numbers.get(0));
System.out.println("the second largest number is " + numbers.get(1));
}
}