# Checking if a number fits in a primitive type

I made a program that asks for a specified amount of numbers and checks if the input number is in the primitive type range. If it is, it "fits" on the primitive type.

Each input number, it checks if the number is in the range of each primitive type MIN and MAX range. If it is between the range, it prints the type(s) it is ranged on.

import java.math.BigInteger;
import java.util.Scanner;

public class Main {

private Scanner in = new Scanner(System.in);

public Main()
{
// Get input on how many numbers to ask for
int t = in.nextInt();
String input;
for(int times = 0; times < t; times++) {
input = in.next();
try {
BigInteger number = new BigInteger(input);
System.out.println(input + " can be fitted in:");
if(number.longValue() < Byte.MAX_VALUE && number.longValue() > Byte.MIN_VALUE)
{
System.out.println("* byte");
}
if(number.longValue() < Short.MAX_VALUE && number.longValue() > Short.MIN_VALUE)
{
System.out.println("* short");
}
if(number.longValue() < Integer.MAX_VALUE && number.longValue() > Integer.MIN_VALUE)
{
System.out.println("* int");
}
// If the longValueExact() returns a greater number than the long max value, then it throws an ArithmeticException
if(number.longValueExact() < Long.MAX_VALUE && number.longValue() > Long.MIN_VALUE)
{
System.out.println("* long");
}
}
catch(NumberFormatException | ArithmeticException e)
{
System.out.println(input + " * nothing");
}
}
}

public static void main(String[] args)
{
new Main();
}
}


I got this "challenge" from this challenge website. It may explain the challenge better.

String input;
for(int times = 0; times < t; times++) {
input = in.next();


There's no need to declare input outside of the loop. It has no advantage at all as you don't need to keep it between iterations. Always minimize the scope.

       // If the longValueExact() returns a greater number than the long max value, then it throws an ArithmeticException


As pointed in a comment, I misread longValueExact as longValue. Updated the answer, so that both are covered.

For longValue, this isn't true and the Javadoc says it pretty clearly:

if this BigInteger is too big to fit in a long, only the low-order 64 bits are returned

For longValueExact, the following is said

If the value of this BigInteger is out of the range of the long type, then an ArithmeticException is thrown.

So checking for exception is correct. If it gets thrown, the number doesn't fit in long and obviously in no smaller type either.

        if(number.longValueExact() < Long.MAX_VALUE && number.longValue() > Long.MIN_VALUE)
{
System.out.println("* long");
}


By definition, there's no long bigger than the biggest long, is it?

So this test is a tautology.

Using longValueExact makes the program correct. With longValue, it wouldn't work and instead of testing if a number fits in a type, you test if its lowest 64 bits do.

Still, letting an exception be thrown for a normal program flow is extremely inefficient as the JIT assumes that exceptions are well... exceptional. Moreover, filling their stacktrace is pretty complicated and slow, as they actually don't exists in an optimized code.

In order to get a faster code, you need to do it the other way round: Convert to BigInteger and then compare. As a bonus to speed, you get compatibility with Java 7.

You should also fix your spacing and braces. Let your IDE do it, it's free.

• the Javadoc you link is for Java7 but BigInteger.longValueExact was added in Java8 – No_signal Jun 7 '15 at 6:46
• @No_signal I simply can't read... fixed it so that both versions are covered. Thanks a bunch! – maaartinus Jun 7 '15 at 11:14