HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2010
0304
tararirarinif文条件式の真偽値と、条件式内での "&" のやっていることについて13解決


tararirarin

リンク

2010/3/4(Thu) 20:47:17|NO.30977

下のスレッドで、yosshidaさんの「stickでのキー入力のふるまいがわからない」を
見て試しているうちに疑問がわいてきました。

(スレッドの内容は、stick による操作がうまくいかないというような内容です。)
スレ主さんは stick によるキーの入力状態を「if KEY=80:」と調べられていましたが、
リファレンスの stick の項を見ると"&"演算子の利用法が載っていたのでそれを試しました。

次のようなプログラムを作り、試してみました。

repeat stick a if a&64 : mes"true" wait 10 loop
Ctrlキーを押すと"true"と表示されました。うまくいきました。
「ふむふむ、if文は、条件式が満たされたときそれ以降の命令を実行するということだから、
 "a&64"は"真"と判断されたのだな。」と考えました。
次に、Ctrlキーと→キーの同時押しで表示させようと条件式を変更しました。

repeat stick a if (a&64)&(a&4) : mes"true" wait 10 loop
すると、エラーこそ出ませんがうまくいきません。
"if(条件式1)&(条件式2)"
このかたちは、「条件式1が真、かつ条件式2も真のとき真となり、次の命令が実行される」
と理解していましたので、今回、「???」となってしまいました。

以前 Jaba をかじりかけたことがあるのですが、(すぐ挫折しました^^;)
stick のキーに割り振られた数字が、1,2,4,8、・・・と倍々になっているのを見て、
ビット演算?を思い出しました。(and や xor が何かやってました。^^;)

そこで次のような文を実行してみました。

mes 68&3 mes 68&5 mes 6>3 mes 6>9
なんとエラーにならない!そしてなんとなくつかめてきました。
・条件式が真なら"1"を、偽なら"0"を返すということ。
・"&"演算子は、両隣の数値を二進数になおし、各桁をくらべ、両方とも"1"の桁を"1"として
 取り出した数値をかえすものだということ。

if a&64 : mes"true"
この文の条件式の「a&64」の部分は、 a にいろんなキー情報が入力されていても、
64 に対応したビットが取り出されるので Ctrlキーが押されていれば "64"が返され、
mes"true" が実行された、とわかりました。

if (a&64)&(a&4) : mes"true"
これの場合は (a&64)&(a&4) が"0"になることがわかりましたので、それで mes"true" が
実行されなかったのだなと思いました。

つまりHSPでは、if文は「条件式に返された値が"0"なら偽、"1〜"なら真とする」
ということなのかな?と予想をたてました。
(条件式が"-1"や"0.1"のような場合は、もう頭がパンクしそうなので考えていません。)

この考察結果は、まずまずではあるがどうも正確ではないという気がしています。

長文で読みづらく失礼しましたが、この考えは合っていますでしょうか?
なにか訂正や補足があれば、ぜひお願いします。

("&"演算子は、"="のように、条件式内で使われたときとそのほかで使われたときで
 役割が違うのか、それとも同じなのか疑問は残っているのですが、
 ここでは同じ役割を果たしているとして考えていきました。)



この記事に返信する


腱鞘炎

リンク

2010/3/4(Thu) 21:23:19|NO.30982

その通りで、0だと偽、1以上だと真とされます。
そして、0以下(-1等)でも偽になります。
逆に偽だと0、真だと1が返されます。
&は、条件式内でもその他でも役割は同じです。

その他のことは自信が無いので他の人に回答を任せます。



晩御飯

リンク

2010/3/4(Thu) 21:35:54|NO.30983

概ねその通りかと。

>・"&"演算子は、両隣の数値を二進数になおし、各桁をくらべ、両方とも"1"の桁を"1"として
 取り出した数値をかえすものだということ。
別にAND演算子は両隣の数値を二進数に直したりはしませんが、
多分分かってると思うので割愛。


if (a&64)&(a&4) : mes"true"
が上手くいかないのは、stick命令の「ボタンが押された瞬間だけを検出する」と言う仕様のせいかと。
コンマ数秒間で複数キーを全く同時に押すのは中々至難の業かと。
stick命令でも設定を変えれば上手くいく筈なのにできなかったのでgetkeyで妥協しました。

repeat redraw 0 pos : color : boxf getkey ctrl, 17 getkey right, 39 if( ctrl )&( right ) : pos 0, 0 : color 255, 255, 255 : mes "true" // AND演算 getkey esc, 27 : if( esc ) : break redraw 1 wait 10 loop end



tsuka

リンク

2010/3/4(Thu) 22:03:21|NO.30988

>そして、0以下(-1等)でも偽になります。
0以下は真じゃなかったかのぅ。
最近物覚えが悪くてのぅ。ふぉっふぉっふぉ。



GENKI

リンク

2010/3/4(Thu) 22:42:17|NO.30991




SYAM

リンク

2010/3/4(Thu) 22:50:27|NO.30992

※あげあしとり

0以下は0含んじゃうから偽にもなるもん!



Ve

リンク

2010/3/4(Thu) 23:11:16|NO.30993

そんな書き方をするから・・・うわーなんだおまえr



tararirarin

リンク

2010/3/4(Thu) 23:22:29|NO.30994

腱鞘炎さん ありがとうございます。
>その通りで、0だと偽、1以上だと真とされます。
>そして、0以下(-1等)でも偽になります。
>逆に偽だと0、真だと1が返されます。
>&は、条件式内でもその他でも役割は同じです。

やはり&の役割は同じですか。・・・0が偽で1以上が真、また、偽は0で1は真・・・。
そうか、なんと言ったらいいか、より理解が進みました!^^
改めて言われると太鼓判を押していただいたみたいで、すっきりしました。


晩御飯さん
>別にAND演算子は両隣の数値を二進数に直したりはしませんが、
>多分分かってると思うので割愛。

そうでした。モニター上で十進数表示なだけで、二進数に直さなくても
コンピュータは元々二進数で考えている、ということですよね。^^
書き方が不適切でした。

>上手くいかないのは、stick命令の「ボタンが押された瞬間だけを検出する」と言う仕様のせいかと。
>コンマ数秒間で複数キーを全く同時に押すのは中々至難の業かと。

じつは私も最初それに近いものを考えていまして、いろいろ試しました。^^;
その一つがこんなのです。↓

repeat stick a if (a&64)&(a&4) : mes"true" mes cnt wait 200 loop
stick でのキー入力状態を2秒ごとに調べるようにしました。
いつ stick 命令を通過したのかわかるように "mes cnt" を入れました。
"(a&64)&(a&4)" の部分をただの "(a&64)" に変えたり、
"stick a" の部分を "stick a,68" に変えたりして stick の性質を調べました。
その結果、やはり問題は条件式の部分にあるように思えまして。^^;
こう考えました。↓

stick 命令を通過したとき Ctrlキーと→キーが同時に押されていると、
a には"68"が代入されてるので (a&64) はビット演算より"64"が返され、
(a&4) は"4"が返され、

(a&64)&(a&4) → 64&4 → 0 → ゆえに if (a&64)&(a&4) は"偽"となるのでは?
と、こういう感じです。

晩御飯さんに示していただいたスクリプト内の
if( ctrl )&( right )

この部分が非常に興味深かったです!なるほど〜 getkey で得られた"0"や"1"の情報を そのままビット演算子にかけて条件式として if文に入れてやるのですね。 なんだか美しいです。ありがとうございます。 tsukaさん  >0以下は真じゃなかったかのぅ。 ありがとうございます。ちょっと心に留めておき余裕ができたら調べてみたいと思います。



tararirarin

リンク

2010/3/4(Thu) 23:57:23|NO.30997

GENKIさん
 紹介していただいたページを今少し見てきました。
・・・このページは・・・うわあ。すごい!
知りたかった以上のことがてんこ盛りです!
こりゃお気に入りに登録です。ありがとうございます。

ここまでにみなさんに教えていただいたものを参考に、条件式を改良しました。

repeat stick a if ((a&64)=64)&((a&4)=4) : mes"true" wait 10 loop
みごと、Ctrlキーと→キーの同時押しを検出できました。^^
ありがとうございました。
またよろしくお願いします。



tararirarin

リンク

2010/3/5(Fri) 00:01:02|NO.30998

SYAMさん
>0以下は0含んじゃうから偽にもなるもん!
そういやそうですね。私も気がつきませんでした。^^
でも大丈夫です。ちゃんとわかっている(つもり)ですから。



晩御飯

リンク

2010/3/5(Fri) 00:07:32|NO.30999

今更あの&がビット演算じゃなくて論理演算のつもりだったなんて言えない・・・。
HSPでも&&とか||とか書いても良いみたいなんだけど。



tararirarin

リンク

2010/3/5(Fri) 00:49:34|NO.31002

晩御飯さん
>今更あの&がビット演算じゃなくて論理演算のつもりだったなんて言えない・・・。
ありゃりゃ!?私、晩御飯さんのおっしゃった言葉の意味を勘違いしていましたか!
実はまだその言葉の意味をよくわかっていないのですが、すみません、ナマ言いました。><



晩御飯

リンク

2010/3/6(Sat) 21:43:31|NO.31075

>if( ctrl )&( right )
どうもこれはビット演算として処理しているようです。
論理演算として書くなら
>if( ctrl!=0 )&( right!=0 )
でないとダメなようです。

大きく勘違いしていたようです。失礼しました。



tararirarin

リンク

2010/3/6(Sat) 22:37:04|NO.31077

晩御飯さんのおっしゃっていたことがだいたい理解できました。^^

>今更あの&がビット演算じゃなくて論理演算のつもりだったなんて言えない・・・。
この一言で、私は昨日から今日にかけて、「論理演算とビット演算のちがい?」を
調べ考えました。なんとなくですが理解できたと思います。

また一歩おりこうさんになれました。ありごとうございます。



ONION software Copyright 1997-2021(c) All rights reserved.