2

For a problem in HackerRank Java Datatypes (to find in which primitive datatype the given number can be fitted in) when I submit the following code :

import java.util.*;
import java.io.*;
class Solution{
public static void main(String []argh)
{
    Scanner sc = new Scanner(System.in);
    int t=sc.nextInt();

    for(int i=0;i<t;i++)
    {

        try
        {
            long x=sc.nextLong();
            System.out.println(x+" can be fitted in:");
            if(x>=(long)-128 && x<=(long)127)System.out.println("* byte");
            if(x>=(long)Short.MIN_VALUE && x<=(long)Short.MAX_VALUE)System.out.println("* short");
            if(x>=(long)Integer.MIN_VALUE && x<=(long)Integer.MAX_VALUE)System.out.println("* int");
            if(x>=(long)Long.MIN_VALUE && x<=(long)Long.MAX_VALUE)System.out.println("* long");
        }
        catch(Exception e)
        {
            System.out.println(sc.next()+" can't be fitted anywhere.");
        }

    }
}

}

it passes all the test cases. But when i submit the following code :

import java.util.*;
import java.io.*;
class Solution{
public static void main(String []argh)
{
    Scanner sc = new Scanner(System.in);
    int t=sc.nextInt();

    for(int i=0;i<t;i++)
    {

        try
        {
            long x=sc.nextLong();
            System.out.println(x+" can be fitted in:");
            if(x>=(long)-128 && x<=(long)127)System.out.println("* byte");
            if(x>=-1*(long)Math.pow(2,15) && x<=(long)Math.pow(2,15)-1)System.out.println("* short");
            if(x>=-1*(long)Math.pow(2,31) && x<=(long)Math.pow(2,31)-1)System.out.println("* int");
            if(x>=-1*(long)Math.pow(2,63) && x<=(long)Math.pow(2,63)-1)System.out.println("* long");
        }
        catch(Exception e)
        {
            System.out.println(sc.next()+" can't be fitted anywhere.");
        }

    }
}

}

it fails some test cases.

This is one of the testcases that do not pass (downloaded from HackerRank)

17 9223372036854775808 9223372036854775807 -9223372036854775808 -9223372036854775807 4294967296 4294967295 -4294967296 -4294967295 65536 65535 -65536 -65535 256 255 -256 -255 12222222222222222222222222222222222222222221

Why so? Has it anything to do with the return type of Math.pow()? Any help is appreciated. :)

cnova
  • 725
  • 2
  • 9
  • 22
  • 1
    lemme guess it doesn't pass for Math.pow(2,63) right? – nafas Sep 18 '15 at 11:59
  • 1
    Please tells some values that are not accepted. – Johnny Willer Sep 18 '15 at 12:01
  • 1
    This is one of the testcase that does not pass (downloaded from HackerRank) 9223372036854775808 9223372036854775807 -9223372036854775808 -9223372036854775807 4294967296 4294967295 -4294967296 -4294967295 65536 65535 -65536 -65535 256 255 -256 -255 12222222222222222222222222222222222222222221 – cnova Sep 18 '15 at 12:06
  • @nafas - Yeah i think so. – cnova Sep 18 '15 at 12:13
  • @JohnnyWiller - i tried the numbers and i found that `9223372036854775807` and `-9223372036854775808` do not give the desired result. They just give `9223372036854775807 can be fitted in:` and nothing further. – cnova Sep 18 '15 at 12:16
  • @cnova: try `9223372036854775807l` ;-) – serv-inc Sep 18 '15 at 12:18
  • @user - I tried `92233720368547758071` and `9223372036854775807l` both and it is showing the same result for both `n can't be fitted anywhere` – cnova Sep 18 '15 at 12:21
  • @cnova the problem is Math.pow(2,63) its just too large to be representable as double – nafas Sep 18 '15 at 12:24
  • @cnova: Do `System.out.println(9223372036854775807L);` and `System.out.println(9223372036854775807l);` not work? – serv-inc Sep 18 '15 at 12:30
  • In case you still have no achievement for your problem, I have updated my answer. – Johnny Willer Sep 18 '15 at 12:59
  • @nafas but i am able to represent `Math.pow(2,63)` both as `long` and `double`. Interesting finding : `(long)Math.pow(2,63)` and `(long)(Math.pow(2,63)-1)` have same value. o.O – cnova Sep 18 '15 at 14:36

4 Answers4

2

The problem is with Math.pow(2, 63), as discussed in this question: Inconsistent behaviour of primitive integer types in Java

Math.pow returns an double, when the cast occurs maybe you can lose some information.

If you want that IF works, if( x >= -1 * (long) Math.pow(2,63) && x<=(long) Math.pow(2,63) -1 ) System.out.println("* long");

you need to add a bracket, like x<=(long) ( Math.pow(2,63)-1 )

if(x>=-1*(long)Math.pow(2,63) && x<=(long) ( Math.pow(2,63)-1 ) )System.out.println("* long");

Community
  • 1
  • 1
Johnny Willer
  • 3,717
  • 3
  • 27
  • 51
  • Thanks :) I got my answer from the link attached. And yeah `x<=(long) ( Math.pow(2,63)-1 )` is the correct comparison for upper bound, but for lower bound i am still off by `1` when i calculate `-1*(long)Math.pow(2,63)` which is equal to `-9223372036854775807` but it should be `-9223372036854775808` – cnova Sep 18 '15 at 14:41
2

There's actually a better way to solve the problem! It's actually suggested in the title of the Problem Statement itself: 'MIN_VALUE' & 'MAX_VALUE'

The wrapper classes: Byte, Short, Integer & Long all have the static fields 'MIN_VALUE' & 'MAX_VALUE' which describe the limits of the primitive data types that they wrap around.

Using these fields, we can re-write your solution in the following way:

try {
    long x=sc.nextLong();

    System.out.println(x + " can be fitted in:");

    if(x >= Byte.MIN_VALUE && x <= Byte.MAX_VALUE)
        System.out.println("* byte");
    if(x >= Short.MIN_VALUE && x <= Short.MAX_VALUE)
        System.out.println("* short");
    if(x >= Integer.MIN_VALUE && x <= Integer.MAX_VALUE)
        System.out.println("* int");
    if(x >= Long.MIN_VALUE && x <= Long.MAX_VALUE)
        System.out.println("* long");
}
catch(Exception e) {
    System.out.println(sc.next()+" can't be fitted anywhere.");
}
1

Simple test:

//prints 8000000000000000
System.out.println( Long.toHexString( Long.MIN_VALUE ) );
//prints 8000000000000001
System.out.println( Long.toHexString( (-1*(long)Math.pow(2,63)) ) );
//prints 7fffffffffffffff
System.out.println( Long.toHexString( Long.MAX_VALUE ) );
//prints 7ffffffffffffffe
System.out.println( Long.toHexString( (long)Math.pow(2,63) -1 ) );

Running that you see that you subtract -1 from the wrong value.

The problem most probably comes from double not being able to precisely represent the value 263.

Thomas
  • 87,414
  • 12
  • 119
  • 157
  • I tried your suggestion, but had another test case failed : `22 0 1 -1 18446744073709551616 -18446744073709551616 18446744073709551615 -18446744073709551616 32768 -32768 32767 -32767 2147483648 2147483647 -2147483648 -2147483647 128 127 -128 -127 123123123333333333333333333333333313123123 234444444444444444444444444444444444444 -1222222` – cnova Sep 18 '15 at 19:42
-2

All of the possible ways to achieve the goal:

if(x>=Byte.MIN_VALUE && x<=Byte.MAX_VALUE)System.out.println("* byte");

if(x>=-32768 && x<=32767)System.out.println("* short");

if(x>=-2147483648 && x<=2147483647)System.out.println("* int");

// if(x>=-9223372036854775808L && x<=9223372036854775807L) for Long -> OR

// if(x>=Long.MIN_VALUE && x<=Long.MAX_VALUE) for Long -> OR

if(x>=-1*(long)Math.pow(2,63) && x<=(long)Math.pow(2,63)-1)

System.out.println("* long");
Frightera
  • 4,773
  • 2
  • 13
  • 28
  • 1
    Is there something wrong with (i) `Character.MIN_VALUE/MAX_VALUE` (ii) `Short.MIN_VALUE/MAX_VALUE` (iii) `IntegerMIN_VALUE/MAX_VALUE`? and how does this code magically avoid the `Math.pow(2,63)` problem that was extensively addressed above six years ago? – user207421 Jun 07 '21 at 10:30
  • 1)Chracter is not an integer so obviously it won't have any min or max value. ii) and iii) Look, I have already given example of DataType.MIN_VALUE/MAX_VALUE for others (Byte and Long in this example) -> so not given the same for short and int. iv)Math.pow(2,63) -> gives you the power of 2 to the 63rd power and converting this to long helping here to compare it with long value with the range. It can also be compared with the max value of long i.e., 9223372036854775807 but use l or L in the last of the integer to realise the compilor that it is Long value. – Ravi Sourav Jun 07 '21 at 11:01