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


HSPTV!掲示板


未解決 解決 停止 削除要請

2009
0829
semunaビット演算子と条件演算子10解決


semuna

リンク

2009/8/29(Sat) 03:32:15|NO.27387


*main a=1 stick key,256 if (key & 256) & (a==1):mes "OK" wait 10 goto *main

上記のスクリプトなんですが、
左クリックすると、OKとでると思っているんですが、
思うとおりに動いてくれません・・・。
ビット演算子と条件演算子の&が、何か悪いのかなと
思っているのですが、小一時間考えても分かりませんでした・・・。
条件演算子をANDではなく、ORに変えると、その動きはするようなんですが・・・。

どこが悪いのか教えていただけませんか?



この記事に返信する


ANTARES

リンク

2009/8/29(Sat) 03:51:53|NO.27390

 以下を実行して考えてみてください。

key=$FFFFFFFF
mes key & 256
a=1
mes a==1

 それでもわからなければ「ビット演算」について勉強してください。
最近、似たような質問があったので探してみるのもいいかも。



774

リンク

2009/8/29(Sat) 08:25:49|NO.27398

semuna さんが不思議に思っているのは、こう言う事ですかね??


if (0x100){ // 0x100 = 256 mes "1" } if (1){ mes "2" } if (1 & 1){ mes "3" } if (1 & 0x100){ mes "4" // これだけ真にならない }



M

リンク

2009/8/29(Sat) 12:39:29|NO.27404

もうすこし言葉を足してあげれば、きちんと動く(しかもわかりやすい)ようになると思います。

if ((key & 256)!0) and (a==1):mes "OK"
「keyと256を論理積で計算した結果が0以外で、aが1だったら"OK"」



GENKI

リンク

2009/8/29(Sat) 14:45:27|NO.27406

以下、私のサイトの掲示板からほぼコピペ。

&はビット演算をやってるだけなので
((key&256)!0) & (a=0)
のようにしてやる必要があります。
何が起きているのかは下記サンプルとビット演算について調べればわかると思います。

;------------------------------------
;確認サンプル
*main
redraw 1 : await 16 : redraw 0 : color 255, 255, 255 : boxf : color : pos 0,0

stick key, 2047
mes "スペースキーを押してください。"

flg = 0
if ((key&16)!0) & (flg=0) : mes "((key&16)!0) & (flg=0)"
if (key&16) & (flg=0) : mes "((key&16)!0) & (flg=0)"

mes "------------"
mes "((key&16)!0) = " + ((key&16)!0)
mes "(key&16) = " + (key&16)
mes "(flg=0) = " + (flg=0)
mes "------------"
mes "((key&16)!0) & (flg=0) = " + (((key&16)!0) & (flg=0))
mes "(key&16) & (flg=0) = " + ((key&16) & (flg=0))

goto *main
;------------------------------------

関連資料:HSP開発wiki
http://hspdev-wiki.net/?HSP%B9%D6%BA%C2%2F%A5%D3%A5%C3%A5%C8%B1%E9%BB%BB
http://hspdev-wiki.net/?%BE%AE%A5%EF%A5%B6%2F%A5%D3%A5%C3%A5%C8%C1%E0%BA%EE



shinkun

リンク

2009/8/29(Sat) 17:08:58|NO.27409

この問題、1 ヶ月ちょいの間で多くの人が躓いていますね。
これだけ多くの人が躓いているのですから、きっと今後も後を絶えないでしょうね。

このように誤解を起こしやすい仕様なら、いっそ言語仕様を変更した方がいいんじゃないでしょうか?
論理 AND, OR をビット AND, OR で代用するから、こんな問題が起こるのです。論理 AND, OR はきちんと論理演算として実装するべきではないかと思います。

一時的には、stick 命令のリファレンスやサンプル等で

stick key if (key & 1): x++ if (key & 2): y++
なんて記述せずに、

stick key if ((key & 1) != 0): x++ if ((key & 2) != 0): y++
と、示しておくだけでもかなりの効果はあると思います。
stick 命令がらみで躓く人が多いようですので。



GENKI

リンク

2009/8/30(Sun) 00:23:37|NO.27419

>>shinkunさん
1個のときは

if key & 1 : x++
このままでいいんじゃないでしょうか。
1つのときでも例が((key & 1) != 0)となっているとif命令が0か1しか上手く動かず、0,1以外を指定するのは問題があるかのように思われてしまいそうな気がします。

複数の条件を使用するときの例として、1例を加えたほうがいいような気がします。

if ((key & 256)!0) and (a=1):mes "OK"


この件は質問が多いのでHSP開発wikiに解説ページ作りました。
http://hspdev-wiki.net/?%BE%AE%A5%EF%A5%B6%2Fstick%CC%BF%CE%E1%A4%CE%BB%C8%A4%A4%CA%FD
お気づきの点がありましたら、加筆・訂正をご自由にお願いします。



ANTARES

リンク

2009/8/30(Sun) 06:55:56|NO.27421

 私は「if (key&256)==256 & a==1」派



ANTARES

リンク

2009/8/30(Sun) 07:41:11|NO.27427

 あ、違った。
ユーザーはShiftキー+クリックして何か別のことを
させようとしているのかもしれない。
だから「『Shiftキー+クリック』なんて操作には
対応してません」ということを示すために、
「if key==256 & a==1」とすべきです。

 もっとも、「うっかりほかのキーに触ってしまっても無視してあげよう」と
いう考え方もあるかもしれません。

 ほとんどの場合、どちらでもかまいませんが、場合によっては
どちらにするかで操作性が大きく変わる場合がありますので、
注意が必要です。



shinkun

リンク

2009/8/30(Sun) 11:30:02|NO.27436

> GENKI さん

> if命令が0か1しか上手く動かず、0,1以外を指定するのは問
> 題があるかのように思われてしまいそうな気がします。

論理演算とビット演算の区別の無い現状では、むしろそのように認識されていた方が、今回のような問題に遭遇する事がないので幸せじゃないかと思います。記述量が増えるので手間は掛かりますが、それ以外の実害もない訳ですし。
よりベターなのは、条件式には「=, !, <, >, <=, >=」の比較演算子(+論理演算子)を使っていなければならない、と認識される事ですね。条件式の結果が 0, 1 以外だと問題があるという認識は、比較演算の結果が HSP ではどう表現されるのかを知らないといけないですから(まぁ、0 or 1 になるんですけれども)、知らなくても良い内部実装の話に踏み込みすぎてる感があります。

if x+1: y++ ; エラー!! 比較演算子を使っていない!! if x+1 ! 0: y++ ; OK!! 比較演算子を使っている!!
M さんもおっしゃっているように、比較演算子付けた方が意味も分かりやすいと思います。


> 複数の条件を使用するときの例として、1例を加えたほうがいいような気がします。

条件が 1 個の時と 2 個以上の時で記述の仕方が変わってくるという非対称性が気持ち悪いですが、過ちを減らすという意味ではそれでも十分良いと思います。
いずれにせよ、それを提示してお終いにするのではなく、言語仕様の変更、つまり、本当の意味で論理演算をする論理演算子を定義するのを最終目標として欲しい所です。要は、C 言語の「&&」や「||」と同等の物を作って欲しい訳です。結局 C です、ハイ。なんかスイマセン。

解説情報を公開する事は大変重要でありがたい事なのですが、公式マニュアルとか、それに匹敵する程有名な解説サイトなど、開発を始めるに先立っての基礎知識を得る場所にそのような解説が無い限りは、結局、問題が起こった後の対処療法にしかならないんですよね。そうじゃなくて、そもそもそんな問題が起こらない予防をしておくのが重要なんじゃないかと思うのです。中でも言語レベルで予防線が張れると完璧なので、こうしてくどい位に言ってるのですが…。
(そんな予防と成り得る公式マニュアルには、注意書きとして論理演算がビット演算として実装してある旨の1 文があり、「よ〜く」読んでおけばこの問題に躓かないと思うのですが、やっぱり皆、リファレンスやサンプルしか読まれていないんですかね…。p_;)

まぁ、このような事もあって、現状の言語仕様・マニュアル・リファレンスに、どこかしらマズイ所があるためこういう惨状になっており、何かしらの対策を立てる必要があるのではないかと思う訳です。


> ANTARES さん

> 「if key==256 & a==1」とすべきです。

それは、これまでの話とはまた別の話だと思いますよ。
これまで GENKI さん、ANTARES さんの挙げられた条件式達とは意味も挙動も全く違うので、どちらでも構わない事は無く、自分のやりたい事に合う方をよく考えて、適切な方を選択すべきです。



semuna

リンク

2009/8/30(Sun) 15:00:35|NO.27450

すみません、返信遅れてしまいました・・・。
数々の解答をありがとうございます!

たくさんの方々がおっしゃられている、
論理演算がビット演算として実装されてあるということで
解決することが出来ました。

shinkunさんのおっしゃっている通り
公式のマニュアルの注意書きをよく見ていませんでした^^;
私自身C言語を触っていたので、こんな言語仕様があるとは、
思いもよりませんでした。

私の調べ方が悪かったようで、すみませんでした。
そして、たくさんの方々の解答、ありがとうございました。



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