当我提交以下代码时,HackerRank Java Datatypes中的问题(找到可以适合给定数字的原始数据类型):
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.");
}
}
}
}
它通过了所有测试用例。但是当我提交以下代码时:
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.");
}
}
}
}
它失败了一些测试用例。
这是未通过的测试用例之一(从HackerRank下载)
17 9223372036854775808 9223372036854775807 -9223372036854775808 -9223372036854775807 4294967296 4294967295 -4294967296 -4294967295 65536 65535 -65536 -65535 256 255 -256 -255 12222222222222222222222222222222222222222221
为什么这样?它与Math.pow()的返回类型有什么关系吗?任何帮助表示赞赏。 :)
答案 0 :(得分:1)
简单测试:
//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 ) );
运行你看到你从错误的值中减去-1。
问题很可能来自于double
无法准确表示值2 63 。
答案 1 :(得分:1)
问题在于Math.pow(2, 63)
,正如此问题所述:Inconsistent behaviour of primitive integer types in Java
Math.pow
返回一个双精度值,当投射发生时可能会丢失一些信息。
如果您希望IF有效,if( x >= -1 * (long) Math.pow(2,63) && x<=(long) Math.pow(2,63) -1 ) System.out.println("* long");
您需要添加一个括号,例如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");
答案 2 :(得分:0)
实际上有更好的方法来解决问题!实际上,在“问题陈述”标题中建议使用“ MIN_VALUE”和“ MAX_VALUE”
包装类:Byte,Short,Integer和Long均具有静态字段“ MIN_VALUE”和“ MAX_VALUE”,这些静态字段描述了它们环绕的原始数据类型的限制。
使用这些字段,我们可以通过以下方式重新编写您的解决方案:
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.");
}
答案 3 :(得分:-2)
实现目标的所有可能方式:
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");