Java数据类型 – Hacker Rank

huangapple go评论58阅读模式
英文:

Java Datatypes - Hacker Rank

问题

我正在尝试解决 HackerRank 上的一个问题我需要做的是在这里列出的 [链接][1]代码的解释),我已经设法使代码运行并且能够工作但是有两个测试未通过[![在这里输入图片描述][2]][2]

这是我的代码

```java
import java.util.Scanner;

public class JavaDatatypes {
    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 + " 可以容纳于:");

                int[] bits = {8, 16, 32, 64};
                String[] strings = {"byte", "short", "int", "long"};
                for (int j = 0; j < bits.length; j++) {
                    long range = (long) (Math.pow(2, bits[j] - 1));
                    if (x >= -range && x <= range - 1) {
                        System.out.println("* " + strings[j]);
                    }
                }
                // 完成代码
            } catch (Exception e) {
                System.out.println(sc.next() + " 无法放入任何数据类型中。");
            }
        }
    }
}

我查看了预期的输出,它期望将 9223372036854775807 作为一个 long 输出,但是我的代码没有将其作为 long 输出,我不确定原因。


<details>
<summary>英文:</summary>

I am trying to solve a problem on hacker rank so what I have to do is listed [here][1] (explanation of the code), and I have managed to make the code run and work, but it fails 2 of the tests.[![enter image description here][2]][2]

here is my code.

    import java.util.Scanner;
    
    public class JavaDatatypes {
        public static void main(String[] argh) {
            Scanner sc = new Scanner(System.in);
            int t = sc.nextInt();
            for (int i = 0; i &lt; t; i++) {
                try {
                    long x = sc.nextLong();
                    System.out.println(x + &quot; can be fitted in:&quot;);
    
                    int[] bits = {8, 16, 32, 64};
                    String[] strings = {&quot;byte&quot;, &quot;short&quot;, &quot;int&quot;, &quot;long&quot;};
                    for (int j = 0; j &lt; bits.length; j++) {
                        long range = (long) (Math.pow(2, bits[j] - 1));
                        if (x &gt;= -range &amp;&amp; x &lt;= range -1) {
                            System.out.println(&quot;* &quot; + strings[j]);
                        }
                    }
                    //Complete the code
                } catch (Exception e) {
                    System.out.println(sc.next() + &quot; can&#39;t be fitted anywhere.&quot;);
                }
            }
        }
    }



I have looked at the expected output and it expects `9223372036854775807` to be outputed as a long, and my code isn&#39;t outputting that as a long I am not sure why.


  [1]: http://hackerrank.com/challenges/java-datatypes/problem
  [2]: https://i.stack.imgur.com/aSGcZ.png

</details>


# 答案1
**得分**: 1

问题在于你的代码中使用了 `double pow(double a, double b)`。当结果接近 `Long.MAX_VALUE` 时,结果会被**舍入**。你可以通过使用 `BigInteger` 进行验证:

```java
String str1 = BigInteger.valueOf(2).pow(bits[j] - 1).toString();
String str2 = String.valueOf((long)Math.pow(2, bits[j] - 1));

这些字符串应该每次都相等,但对于 2^16,它们并不相等。这就是为什么对于 2^16,你的 x <= range - 1 不正确。


你不需要使用 for loop 来进行检查。Java 有像 Byte.MIN_VALUEByte.MAX_VALUE 这样的常量。

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 + " 可以放在以下类型中:");
            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");
            System.out.println("* long");
        } catch(Exception e) {
            System.out.println(sc.next() + " 无法放在任何类型中。");
        }

    }
}
英文:

Problem in you code is that you use double pow(double a, double b). When you have result closer to Long.MAX_VALUE - the result is rounded. You can check it by BitInteger:

String str1 = BigInteger.valueOf(2).pow(bits[j] - 1).toString();
String str2 = String.valueOf((long)Math.pow(2, bits[j] - 1));

These strings should be equal every time, but for 2^16 - it's not. That's why for 2^16 your x &lt;= range - 1 is not correct.


You do not need to use for loop to check this. Java has constants like Byte.MIN_VALUE, Byte.MAX_VALUE.

public static void main(String[] argh) {
    Scanner sc = new Scanner(System.in);
    int t = sc.nextInt();

    for (int i = 0; i &lt; t; i++) {

        try {
            long x = sc.nextLong();
            System.out.println(x + &quot; can be fitted in:&quot;);
            if (x &gt;= Byte.MIN_VALUE &amp;&amp; x &lt;= Byte.MAX_VALUE)
                System.out.println(&quot;* byte&quot;);
            if (x &gt;= Short.MIN_VALUE &amp;&amp; x &lt;= Short.MAX_VALUE)
                System.out.println(&quot;* short&quot;);
            if (x &gt;= Integer.MIN_VALUE &amp;&amp; x &lt;= Integer.MAX_VALUE)
                System.out.println(&quot;* int&quot;);
            System.out.println(&quot;* long&quot;);
        } catch(Exception e) {
            System.out.println(sc.next() + &quot; can&#39;t be fitted anywhere.&quot;);
        }

    }
}

答案2

得分: 1

只需省略对64位和long的检查。

如果long x = sc.nextLong();成功执行而没有异常,你已经知道这个数字适用于long类型。所以,如果没有异常,你可以始终打印“* long”。

关于使用Math.pow()的一个注意事项:它基于浮点算术,因此可能涉及小的舍入误差。2的幂可以通过位移运算来计算,因此

long range = (long) (Math.pow(2, bits[j] - 1))

可以替换为

long range = 2L << (bits[j] - 1)

这可以得到精确的结果,而且比使用Math.pow()更快。

英文:

Just omit the check for 64 bits and long.

If long x = sc.nextLong(); succeeds without exception, you already know that the number fits into the long type. So, you can always print "* long" if you didn't get an exception.

One remark on using Math.pow(): it's based on floating-point arithmetic and as such, it might involve small rounding errors. Powers of 2 can be computed by bit-shifting, so

long range = (long) (Math.pow(2, bits[j] - 1))

can be replaced by

long range = 2L &lt;&lt; (bits[j] - 1)

This gives exact results and also is faster than Math.pow().

huangapple
  • 本文由 发表于 2020年10月1日 13:14:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/64149457.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定