JavaA2Z

KAB-studio > プログラミング > JavaA2Z > 算術右シフトとは

算術右シフト

日本語 算術右ずらし
英語 arithmetic right shift、signed right shift
ふりがな さんじゅつみぎしふと
フリガナ サンジュツミギシフト

解説

右方向にビットシフトする際に、左端のビットには「シフト前の値」をセットする方法。
>>演算子」によるビットシフト。
 
ビットシフトをう際の、左端のビット処理には2種類ある。
 
・算術右シフト
「シフト前の値をセットする」方法。左端のビットが0であれば0、1であれば1をセットする。
 
論理右シフト
「常に0をセットする」方法。左端のビットに関わらず常に0をセットする。
 
算術右シフトは左端のビットが1の場合には1をセットする。
これは、プラスマイナスの「符号」が左端のビットにあり、このビットの値をそのまま残すことで「正負を維持する」ことができ、さらに「ビットシフトによる計算」ができるためである。
 
int等の整数は、左端のビットが「符号」を表すビットとなっている。0がプラス、1がマイナスである。
算術右シフトは左端のビットを維持するため、この符号も維持される。つまり、マイナスの値を算術右シフトした結果はマイナスとなる。
さらに、整数のマイナスの値は「2の補数」という形式で表現されており、いわば0と1が逆の状態となる。そのため、マイナスの場合に左端から1を追加していくことで、プラスの時に0が追加されるのと同じ結果となる。
ビットシフトは「2進数形式で桁を減らす」ことになるため、その結果は「シフト数だけ2で割る」こととなる(ただし余りが出る場合もある)。
マイナスの値の場合、左端に1を追加していくことでこの計算をうことができる。
 
つまり、算術右シフトをうことで、マイナスの場合にも「シフト数だけ2で割る」という計算をうことができる。
この「計算ができる」という点が「算術」の理由である。
 
算術右シフトはこのように「計算をうためのビットシフト」である。
純粋に「ビットを移動したい」という場合には不便なため、その場合には「論理右シフト」を使用した方がいいだろう。
 
左方向は「<<演算子」による「左シフト」のみである。「算術左シフト」「論理左シフト」は存在しない。
符号ビットは左端にあり、右端のビットは単なる「2進数での一番小さい桁」である。そのため、「<<演算子」は常に0をセットする。「算術」「論理」といった違いが意味をなさないことになる。

参考サイト

  • (参考サイトはありません)

(KAB-studioからのおしらせです)

サンプルプログラム(とか)サンプルを別ウィンドウで表示サンプルをクリップボードへコピー(WindowsでIEの場合のみ)

// Sample.java
public class Sample
{
    public static void main( String[] args )
    {
        long l;

        // -8を右に2ビットシフトします。
        // 左端に1が入っていることを確認してください。
        l = -8;
        System.out.println( l );
        outputLongBit( l );
        // -8
        // 1111111111111111111111111111111111111111111111111111111111111000
        l = l >> 2;
        System.out.println( l );
        outputLongBit( l );
        // -2
        // 1111111111111111111111111111111111111111111111111111111111111110

        // このように、>>演算子による「算術右シフト」を行うと、
        // 符号が維持されます。
        // さらに、シフト数だけ2で割った値になります。
        // このように「計算」を行うために使用するため「算術右シフト」と
        // いいます。

        // 参考:>>>演算子による「論理右シフト」の場合。
        l = -8;
        l = l >>> 2;
        System.out.println( l );
        outputLongBit( l );
        // 4611686018427387902
        // 0011111111111111111111111111111111111111111111111111111111111110

        // このように、左端のビットに0がセットされることで、
        // 値としては変になりますが、ビットとしてはむしろ
        // こちらの方が希望する結果でしょう。
    }

    /**
    *   long型変数をビット形式で出力します。
    */
    private static void outputLongBit( long l )
    {
        // long型変数をビット形式で文字列化します。
        String source = Long.toBinaryString( l );
        // 左0埋めします。
        StringBuffer strbuf = new StringBuffer();
        forint iF1 = source.length(); iF1 < 64; ++iF1 )
        {
            strbuf.append( "0" );
        }
        strbuf.append( source );

        System.out.println( strbuf.toString() );
    }
}
// Sample.java
public class Sample
{
    public static void main( String[] args )
    {
        long l;

        // -8を右に2ビットシフトします。
        // 左端に1が入っていることを確認してください。
        l = -8;
        System.out.println( l );
        outputLongBit( l );
        // -8
        // 1111111111111111111111111111111111111111111111111111111111111000
        l = l >> 2;
        System.out.println( l );
        outputLongBit( l );
        // -2
        // 1111111111111111111111111111111111111111111111111111111111111110

        // このように、>>演算子による「算術右シフト」を行うと、
        // 符号が維持されます。
        // さらに、シフト数だけ2で割った値になります。
        // このように「計算」を行うために使用するため「算術右シフト」と
        // いいます。

        // 参考:>>>演算子による「論理右シフト」の場合。
        l = -8;
        l = l >>> 2;
        System.out.println( l );
        outputLongBit( l );
        // 4611686018427387902
        // 0011111111111111111111111111111111111111111111111111111111111110

        // このように、左端のビットに0がセットされることで、
        // 値としては変になりますが、ビットとしてはむしろ
        // こちらの方が希望する結果でしょう。
    }

    /**
    *   long型変数をビット形式で出力します。
    */
    private static void outputLongBit( long l )
    {
        // long型変数をビット形式で文字列化します。
        String source = Long.toBinaryString( l );
        // 左0埋めします。
        StringBuffer strbuf = new StringBuffer();
        for( int iF1 = source.length(); iF1 < 64; ++iF1 )
        {
            strbuf.append( "0" );
        }
        strbuf.append( source );

        System.out.println( strbuf.toString() );
    }
}

この単語を含むページ

「みだし」に含まれているページ

「解説」に含まれているページ

「サンプルプログラムとか」に含まれているページ

はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
Yahoo!ブックマーク 詳細を表示 users
del.icio.us 登録する RSSに登録
サンプルを別ウィンドウで表示
サンプルをクリップボードへコピー(WindowsでIEの場合のみ)
update:2005/12/12
このページは、Javaプログラミング言語についての用語を網羅した辞書「JavaA2Z」の一ページです。
詳しくは「JavaA2Z」表紙の説明をご覧ください。