2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Javaのシフト演算の注意点

Posted at

問題

先日、Twitterに以下の投稿をしました。

この答え、実際に実行せずに分かりますでしょうか?



解答

まずは javap -v の結果から

C:\TEMP>javap -v ShiftTest
Classfile /C:/TEMP/ShiftTest.class
  Last modified 2016/11/08; size 454 bytes
  MD5 checksum 644670dc34f923a57cd1ee900e33c5f0
  Compiled from "ShiftTest.java"
public class ShiftTest
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #7.#16         // java/lang/Object."<init>":()V
   #2 = Fieldref           #17.#18        // java/lang/System.out:Ljava/io/Print
Stream;
   #3 = String             #19            // (1<<31)<<1=0
   #4 = Methodref          #20.#21        // java/io/PrintStream.println:(Ljava/
lang/String;)V
   #5 = String             #22            //  1<<32    =1
   #6 = Class              #23            // ShiftTest
   #7 = Class              #24            // java/lang/Object
   #8 = Utf8               <init>
   #9 = Utf8               ()V
  #10 = Utf8               Code
  #11 = Utf8               LineNumberTable
  #12 = Utf8               main
  #13 = Utf8               ([Ljava/lang/String;)V
  #14 = Utf8               SourceFile
  #15 = Utf8               ShiftTest.java
  #16 = NameAndType        #8:#9          // "<init>":()V
  #17 = Class              #25            // java/lang/System
  #18 = NameAndType        #26:#27        // out:Ljava/io/PrintStream;
  #19 = Utf8               (1<<31)<<1=0
  #20 = Class              #28            // java/io/PrintStream
  #21 = NameAndType        #29:#30        // println:(Ljava/lang/String;)V
  #22 = Utf8                1<<32    =1
  #23 = Utf8               ShiftTest
  #24 = Utf8               java/lang/Object
  #25 = Utf8               java/lang/System
  #26 = Utf8               out
  #27 = Utf8               Ljava/io/PrintStream;
  #28 = Utf8               java/io/PrintStream
  #29 = Utf8               println
  #30 = Utf8               (Ljava/lang/String;)V
{
  public ShiftTest();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>
":()V
         4: return
      LineNumberTable:
        line 4: 0

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #2                  // Field java/lang/System.out:Ljav
a/io/PrintStream;
         3: ldc           #3                  // String (1<<31)<<1=0
         5: invokevirtual #4                  // Method java/io/PrintStream.prin
tln:(Ljava/lang/String;)V
         8: getstatic     #2                  // Field java/lang/System.out:Ljav
a/io/PrintStream;
        11: ldc           #5                  // String  1<<32    =1
        13: invokevirtual #4                  // Method java/io/PrintStream.prin
tln:(Ljava/lang/String;)V
        16: return
      LineNumberTable:
        line 18: 0
        line 19: 8
        line 20: 16
}
SourceFile: "ShiftTest.java"

はい。答えは書いてありますね。

  • (1<<31)<<1=0
  • 1<<32 =1

なのです。

1<<32=1なのはなぜか?

言語仕様に書いてあります。
http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.19

If the promoted type of the left-hand operand is int, then only the five lowest-order bits of the right-hand operand are used as the shift distance.

つまり下5ビットしかみていないので、31が最大。32は0として扱われているので、 1<<32 = 1<<0 = 1 ということ。

言語仕様を読んでみよう

そこには新たな発見があるはず!
https://docs.oracle.com/javase/specs/

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?