はてなキーワード: 排他的論理和とは
プログラミングの基本的手法の1つに、論理演算というものがある。
これは真偽値(真=true、偽=false)同士の組み合わせを評価し、結果をtrue/falseで返すというものだ。
この演算のための演算子の代表的なものがANDとORで、それぞれ論理積と論理和という。
式aとbにtrue/falseのいずれかが定義されているとして、
a AND bだったらaとb両方がtrueのときのみ、演算結果がtrueになり、
a OR bだったらaとbいずれかがtrueであれば、演算結果がtrueになる。
ということは、
ANDの場合は左辺の式がfalseの時点で、右辺を評価するまでもなく演算結果はfalseとなり、
ORの場合は左辺の式がtrueの時点で、右辺を評価するまでもなく演算結果はtrueとなる。
これを短絡評価といい、今どきのプログラミング言語では必ずこの仕掛けが実装されていると。
これは排他的論理和といい、演算子の右辺と左辺の結果が違う組み合わせの場合のみtrueとなる。
つまりa=trueかつb=falseの場合か、a=falseかつb=trueの場合のみ、演算結果(a XOR b)がtrueとなる。
問題は、どういうわけかこのXORには短絡評価が存在しないのだ。
どのプログラミング言語を調べても短絡評価がないので、かなり驚いている。
一体どういうこと?
(追記)
1+1が2にも3にも4にもなるって脳筋の陽キャがよく言うけど、
ここで謎の演算子「+」を持つモノイドを考えてみたい。
まず、前提として、1,2,3,...はモノイドの元 α1,α2,α3,...の簡易記法とする。
モノイドの単位元はα0とする。
α_n+1 = SUCC(α_n)と表すことができることとする。
つまり
α2 = SUCC(α1) α3 = SUCC(α2) = SUCC(SUCC(α1)) ...
である。
α0 = α0 + α0 α1 = α1 + α0 α2 = α2 + α0 ...
である。
α1 + α1 = α2 = SUCC(α1) = α3 = SUCC(SUCC(α1)) = α4 = SUCC(SUCC(SUCC(α1))) ...
となる。
これを満たすことができる関数SUCCは幾つか考えられるが
その1:
defun SUCC(x) = α0
その2:
defun SUCC(x) = if (x equals to α0) then α0 else x
等とすることができる。
その1は 1bit の排他的論理和
α0 + α0 = α0 α0 + α1 = α1 α1 + α0 = α1 α1 + α1 = α2 = SUCC(α1) = α0
その2は 1bit の論理和
α0 + α0 = α0 α0 + α1 = α1 α1 + α0 = α1 α1 + α1 = α2 = SUCC(α1) = α1
である。
脳筋って頭いいんだね
プログラマ「いやぁ、論理演算のパターン多すぎてマジ混乱してきた・・・」
?????「困っているようだね」
プログラマ「そうなんです。論理和 , 論理和の否定, 排他的論理和...。いくつもあって頭が混乱してきたんです。」
?????「それならこれを使いなさい」
プログラマ「ぎゃー!!!あんなにイミフだったif文が視覚的に図式化されてスラスラ書けるぅぅうううう!!!!!あばばばばば!!!!」
?????「そうだろう。君がこの仕事を続ける限り、各集合をひとつの閉曲線(例えば円)の内部で表し、相関関係をその閉曲線の交わり方によって表す図を知っているということは一生役に立つぞ。」
プログラマ「え・・?」
?????「暗黒に染まったif文をキレイに書き直す度にパワーがはるかに増す・・その更新を無限にオレは残している・・その意味がわかるな?」
プログラマ「いきなり意味がわからないことを言いやがって!!こいつ、なんかやばいぞっ!!!!」
ゴゴゴゴゴ....
プログラマ「だめだ!暗黒の力が強烈過ぎて僕のスパゲッティコードの力では太刀打ち出来無い(´・_・`)...!!」
プログラマ「きさま!まさか!!(((((((( ;゚Д゚))))))))ガクガクブルブルガタガタブルブル」
どうーでもいいーですよー。
どうでもいい話ー、聞いてください。
Perlというやつは一応内部的には数値か文字列かをちゃんと分けて変数の管理をしているのです。
でわ、現在ある変数が内部的に数値なのか?内部的に文字列なのか?判別しようと思ったらどうしますか?
こうしてみます。
my @data = ( 100, # 100は内部的に数値 '200' # 200は内部的に文字 ); foreach my $d ( @data ) { if( ($d ^ $d) eq '0' ){ print $d . " = It's numeric\n"; } else { print $d . " = It's string\n"; } }
同じ変数同士を排他的論理和(^)すると、その変数が数値の場合は0になり、その変数が文字列の場合は空文字になるのです。
なぜかって?そりゃ同じ値同士で排他的論理和したら必ず00000000になるでしょう?
で00000000は、数値なら数字の0だし、文字列なら制御コードのNUL文字になるので上記のような処理が成り立つというわけです。
あってますよね?
ってか判別できたからなんだというんだと問われたらぐうの音すら出ません。まったくもってどうでもいい話でした。