スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[PHP] XOR でビット演算させようとして、AND とか OR と同じような動きにならないんだけど変くね?

なんか根本的におかしなことをやっている可能性もあるのですが、
XORで計算する必要がありまして、AND とか OR みたいに扱えるかと
思ったらそうでもなかった、という話。

結局はベタな関数を自作してなんとか対処したのですが、
下記のような感じ。


<?php
//========================================
// 文字列全体をXORマスク
//========================================

function ProcXor( $str, $str2 ){
$ret = "";
//適度にエラーチェック
if( ( strlen( $str ) < 0 ) || ( strlen( $str ) < 0 ) ){
return( $ret );
}elseif( ( strlen( $str ) != strlen( $str ) ) ){
return( $ret );
}
//1文字ずつ XORして結果を文字で返す
for( $i = 0; $i < strlen( $str ); $i++ ){
$c = substr( $str, $i, 1 );
$c2 = substr( $str2, $i, 1 );
$ret .= ( $c xor $c2 ) == 1 ? "1" : "0";
}
return( $ret );
}

//========================================
// メイン
//========================================

$buf = "";
$a = bindec( '10101111' );
$b = bindec( '11111111' );

$buf .= "A:".decbin( $a )."<br />\n";
$buf .= "B:".decbin( $b )."<br />\n";
$buf .= "<hr />";

$c = $a & $b;
$buf .= "A AND B : ".decbin( $c );
$buf .= "<br />\n";
$c = $a | $b;
$buf .= "A OR B : ".decbin( $c );
$buf .= "<br />\n";
$c = $a xor $b;
$buf .= "A XOR B : ".decbin( $c );
$buf .= "<br />\n";
//追記 2010.08.19
$c = $a ^ $b;
$buf .= "A XOR B (^) : ".decbin( $c );
$buf .= "<br />\n";

//追記 2010.08.19 ここまで
$c = ProcXor( decbin( $a ), decbin( $b ) );
$buf .= "A XOR B (2) : ".$c;
$buf .="<br />\n";

include( 'mask.tmpl' );
?>



A として 10101111
B として 11111111

という値を用意して、AND、OR、XOR をかけてみると。

結果は上のとおりで、AND、OR は期待通りの値になるのですが、XOR だけうまくいかない。
排他的論理和ですから、異なってるときだけ真になって、01010000 となるのが正解のはずが、
$a xor $b だと 10101111 とかいう OR と同じ結果を返してくる。

2進10進の値の取り扱いに問題があるのかと思ったのですが、それにしたところで
AND や OR と同じような動きをしてくれないのは具合が悪い。
というわけで、1文字ずつ XOR をかけて(これは正常に見える)その結果を文字列として
重ねていくという変なことをしています。こうすると期待した結果になりました。

2010.08.19 追記

私がへっぽこでした!

下記コメントいただいたように、「xor」は論理演算子で、
ビット演算をさせたいときには「^」のビット演算子を使用すべきでした。

論理演算子
http://php.net/manual/ja/language.operators.logical.php

ビット演算子
http://php.net/manual/ja/language.operators.bitwise.php

というわけで、前述の内容も追記修正しました。ビット演算子「^」を使った
部分はちゃんと計算されてますね。

珍妙自作関数なんかいらんかったんや!
関連記事
スポンサーサイト

テーマ : PHP
ジャンル : コンピュータ

タグ : PHP

comment

管理者にだけメッセージを送る

論理演算子

AND OR XOR は論理演算子でビット演算子ではないですよ
ビット演算子は & | ^ です
論理演算子は && || とも書けます

おぅ?

コメントありがとうございます。

おお、マニュアル確認したら確かに論理演算子でした。
ということはビット演算してるように見えても、

0 (ビット演算XOR) 1 → 1

ではなくて、

0(偽) (論理演算XOR) 1(真) → 1(真)

な、だけなのですな。
エントリ内容修正しました!
検索フォーム
リンク
最新記事
最新コメント
カテゴリ
RSSリンクの表示
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。