| ユーザフォーラムで議論/質問 | マニュアル検索 | ハイライト | ハイライトオフ | ポータル | php spot |
ビット演算子ビット演算子は、整数値の特定のビットの評価や操作を行います。
PHP のシフト処理は算術シフトです。両端からあふれたビットは捨てられます。 左シフトをすると右側にはゼロが埋められます。 符号ビットは左端からあふれて消えます。 つまり、オペランドの符号は維持されないということです。 右シフトの際には、符号ビットと同じ内容が左端から埋められます。 つまり、この場合はオペランドの符号が維持されます。 括弧を使うことで、望みどおりの 優先順位 で処理させることができます。たとえば、$a & $b == true はまず等価かどうかを評価してからビット演算を行いますが ($a & $b) == true はまずビット演算を行ってから等価かどうかを評価します。 &、| そして ^ 演算子の左右のオペランドが文字列の場合、その演算は、 文字列を構成する文字の ASCII 値を使って行います。その結果は文字列になります。 それ以外の場合は、左右のオペランドを integer に変換 し、結果も integer になります。 ~ 演算子のオペランドが文字列の場合、その演算は、 文字列を構成する文字の ASCII 値を使って行います。その結果は文字列になります。 それ以外の場合は、オペランドや演算結果を integer として扱います。 << および >> 演算子のオペランドとその結果は、常に integer として扱います。
PHP の ini 設定 error_reporting はビット値を用いています。
これを用いて、特定のビットを落とす演算の例を見てみましょう。
notice 以外のすべてのエラーを表示させるには、
php.ini ファイルで
まずは E_ALL。 00000000000000000111011111111111 そして E_NOTICE...。 00000000000000000000000000001000 ... これを ~ で逆転させます。 11111111111111111111111111110111 最後に AND (&) を使い、両方ともビットが立っているところをみつけます。 00000000000000000111011111110111
同じ結果を得るもうひとつの方法として、 XOR (^)
を使ってどちらか一方だけ立っているビットを探すという方法もあります。
error_reporting を使って、特定のビットを立てる処理の例を見てみましょう。
通常のエラーとリカバー可能なエラーだけを表示させるには、次のようにします。
この処理は、 E_ERROR 00000000000000000000000000000001 と 00000000000000000001000000000000 を OR (|) 演算子でつないで、 少なくともどちらかのビットが立っているところを取得します。 00000000000000000001000000000001
例1 整数値におけるビット AND、OR および XOR 演算
<?php 上の例の出力は以下となります。 --------- --------- -- --------- result value op test --------- --------- -- --------- Bitwise AND ( 0 = 0000) = ( 0 = 0000) & ( 5 = 0101) ( 1 = 0001) = ( 1 = 0001) & ( 5 = 0101) ( 0 = 0000) = ( 2 = 0010) & ( 5 = 0101) ( 4 = 0100) = ( 4 = 0100) & ( 5 = 0101) ( 0 = 0000) = ( 8 = 1000) & ( 5 = 0101) Bitwise Inclusive OR ( 5 = 0101) = ( 0 = 0000) | ( 5 = 0101) ( 5 = 0101) = ( 1 = 0001) | ( 5 = 0101) ( 7 = 0111) = ( 2 = 0010) | ( 5 = 0101) ( 5 = 0101) = ( 4 = 0100) | ( 5 = 0101) (13 = 1101) = ( 8 = 1000) | ( 5 = 0101) Bitwise Exclusive OR (XOR) ( 5 = 0101) = ( 0 = 0000) ^ ( 5 = 0101) ( 4 = 0100) = ( 1 = 0001) ^ ( 5 = 0101) ( 7 = 0111) = ( 2 = 0010) ^ ( 5 = 0101) ( 1 = 0001) = ( 4 = 0100) ^ ( 5 = 0101) (13 = 1101) = ( 8 = 1000) ^ ( 5 = 0101)
例2 文字列でのビット XOR 演算
<?php
例3 整数値のビットシフト
<?php 上の例の 32 ビットマシンでの出力は、このようになります。 --- BIT SHIFT RIGHT ON POSITIVE INTEGERS --- Expression: 2 = 4 >> 1 Decimal: val=4 res=2 Binary: val=00000000000000000000000000000100 res=00000000000000000000000000000010 NOTE: copy of sign bit shifted into left side Expression: 1 = 4 >> 2 Decimal: val=4 res=1 Binary: val=00000000000000000000000000000100 res=00000000000000000000000000000001 Expression: 0 = 4 >> 3 Decimal: val=4 res=0 Binary: val=00000000000000000000000000000100 res=00000000000000000000000000000000 NOTE: bits shift out right side Expression: 0 = 4 >> 4 Decimal: val=4 res=0 Binary: val=00000000000000000000000000000100 res=00000000000000000000000000000000 NOTE: same result as above; can not shift beyond 0 --- BIT SHIFT RIGHT ON NEGATIVE INTEGERS --- Expression: -2 = -4 >> 1 Decimal: val=-4 res=-2 Binary: val=11111111111111111111111111111100 res=11111111111111111111111111111110 NOTE: copy of sign bit shifted into left side Expression: -1 = -4 >> 2 Decimal: val=-4 res=-1 Binary: val=11111111111111111111111111111100 res=11111111111111111111111111111111 NOTE: bits shift out right side Expression: -1 = -4 >> 3 Decimal: val=-4 res=-1 Binary: val=11111111111111111111111111111100 res=11111111111111111111111111111111 NOTE: same result as above; can not shift beyond -1 --- BIT SHIFT LEFT ON POSITIVE INTEGERS --- Expression: 8 = 4 << 1 Decimal: val=4 res=8 Binary: val=00000000000000000000000000000100 res=00000000000000000000000000001000 NOTE: zeros fill in right side Expression: 1073741824 = 4 << 28 Decimal: val=4 res=1073741824 Binary: val=00000000000000000000000000000100 res=01000000000000000000000000000000 Expression: -2147483648 = 4 << 29 Decimal: val=4 res=-2147483648 Binary: val=00000000000000000000000000000100 res=10000000000000000000000000000000 NOTE: sign bits get shifted out Expression: 0 = 4 << 30 Decimal: val=4 res=0 Binary: val=00000000000000000000000000000100 res=00000000000000000000000000000000 NOTE: bits shift out left side --- BIT SHIFT LEFT ON NEGATIVE INTEGERS --- Expression: -8 = -4 << 1 Decimal: val=-4 res=-8 Binary: val=11111111111111111111111111111100 res=11111111111111111111111111111000 NOTE: zeros fill in right side Expression: -2147483648 = -4 << 29 Decimal: val=-4 res=-2147483648 Binary: val=11111111111111111111111111111100 res=10000000000000000000000000000000 Expression: 0 = -4 << 30 Decimal: val=-4 res=0 Binary: val=11111111111111111111111111111100 res=00000000000000000000000000000000 NOTE: bits shift out left side, including sign bit 上の例の 64 ビットマシンでの出力は、このようになります。 --- BIT SHIFT RIGHT ON POSITIVE INTEGERS --- Expression: 2 = 4 >> 1 Decimal: val=4 res=2 Binary: val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000000010 NOTE: copy of sign bit shifted into left side Expression: 1 = 4 >> 2 Decimal: val=4 res=1 Binary: val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000000001 Expression: 0 = 4 >> 3 Decimal: val=4 res=0 Binary: val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000000000 NOTE: bits shift out right side Expression: 0 = 4 >> 4 Decimal: val=4 res=0 Binary: val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000000000 NOTE: same result as above; can not shift beyond 0 --- BIT SHIFT RIGHT ON NEGATIVE INTEGERS --- Expression: -2 = -4 >> 1 Decimal: val=-4 res=-2 Binary: val=1111111111111111111111111111111111111111111111111111111111111100 res=1111111111111111111111111111111111111111111111111111111111111110 NOTE: copy of sign bit shifted into left side Expression: -1 = -4 >> 2 Decimal: val=-4 res=-1 Binary: val=1111111111111111111111111111111111111111111111111111111111111100 res=1111111111111111111111111111111111111111111111111111111111111111 NOTE: bits shift out right side Expression: -1 = -4 >> 3 Decimal: val=-4 res=-1 Binary: val=1111111111111111111111111111111111111111111111111111111111111100 res=1111111111111111111111111111111111111111111111111111111111111111 NOTE: same result as above; can not shift beyond -1 --- BIT SHIFT LEFT ON POSITIVE INTEGERS --- Expression: 8 = 4 << 1 Decimal: val=4 res=8 Binary: val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000001000 NOTE: zeros fill in right side Expression: 4611686018427387904 = 4 << 60 Decimal: val=4 res=4611686018427387904 Binary: val=0000000000000000000000000000000000000000000000000000000000000100 res=0100000000000000000000000000000000000000000000000000000000000000 Expression: -9223372036854775808 = 4 << 61 Decimal: val=4 res=-9223372036854775808 Binary: val=0000000000000000000000000000000000000000000000000000000000000100 res=1000000000000000000000000000000000000000000000000000000000000000 NOTE: sign bits get shifted out Expression: 0 = 4 << 62 Decimal: val=4 res=0 Binary: val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000000000 NOTE: bits shift out left side --- BIT SHIFT LEFT ON NEGATIVE INTEGERS --- Expression: -8 = -4 << 1 Decimal: val=-4 res=-8 Binary: val=1111111111111111111111111111111111111111111111111111111111111100 res=1111111111111111111111111111111111111111111111111111111111111000 NOTE: zeros fill in right side Expression: -9223372036854775808 = -4 << 61 Decimal: val=-4 res=-9223372036854775808 Binary: val=1111111111111111111111111111111111111111111111111111111111111100 res=1000000000000000000000000000000000000000000000000000000000000000 Expression: 0 = -4 << 62 Decimal: val=-4 res=0 Binary: val=1111111111111111111111111111111111111111111111111111111111111100 res=0000000000000000000000000000000000000000000000000000000000000000 NOTE: bits shift out left side, including sign bit 警告
システムの long 型で扱える範囲以上の整数値をシフトした場合の結果は未定義です。 32ビットシステム上では、32ビット以上の値をシフトしないようにしましょう。 同様に、64ビットシステム上では、64ビット以上の値をシフトしないようにしましょう。 PHP_INT_MAX を超える数のビット演算には、 gmp 拡張モジュールの関数を使いましょう。 pack(), unpack(), gmp_and(), gmp_or(), gmp_xor(), gmp_testbit(), gmp_clrbit() も参照ください。 |
各種マニュアル:
PHPマニュアル |
PEARマニュアル |
Smarty(英語)マニュアル |
PHP-GTKマニュアル |
「ビット演算子」をGoogle検索
|