[リストへもどる]
一括表示

投稿時間:2003/04/23(Wed) 13:46
投稿者名:birth
Eメール:
URL :
タイトル:
ビット演算Andについて
はじめまして。
ASP(VBScript)でコーディングをしているのですが、
下記のソースが正常でない理由と、解決方法とをお教えいただけないでしょうか。
ASPというよりは、VBの質問かと判断しましたので、
こちらで質問させていただきました。よろしくお願いいたします。


Const A = &H00008000
Const B = &H00010000
Const C = &H00020000
Const D = &H00040000

Sub Main()
  Call fLib(A+B,"処理")
End Sub

Function fLib(a,b)
  If ((a And A) = A) Then
    'bを使った処理1
  End If
  If ((a And B) = B) Then
    'bを使った処理2
  End If
  If ((a And C) = C) Then
    'bを使った処理3
  End If
End Function

※このとき、fLib()の処理1、処理2を通ることを
期待しているのですが、全く通りません。
fLib()には、A+Bつまり、&H00018000が渡されているはずで、
それに対して、(a And A)でマスクをかけています。

投稿時間:2003/04/23(Wed) 14:24
投稿者名:nanashi
Eメール:
URL :
タイトル:
Re: ビット演算Andについて
> Const A = &H00008000
> Const B = &H00010000
> Const C = &H00020000
> Const D = &H00040000

↑ここを↓のように記述してください。

Const A As Long = &H00008000&
Const B As Long = &H00010000&
Const C As Long = &H00020000&
Const D As Long = &H00040000&

理由は特に定数Aについてですが、明示的にLong型にしていないとInteger型だとみなされます。
Long型の場合&H000080000は 32768ですが、Integer型だと -32768になります。
このためA+Bが -32768 + 65536、つまり32768となり定数Aと異なるため処理が正常に行われません。

もう一つ、ビット演算を行っているのですから
> Call fLib(A+B,"処理")
という記述は好ましくありません。

Call fLib(A or B,"処理")
とした方が適していると思います。

投稿時間:2003/04/23(Wed) 14:35
投稿者名:birth
Eメール:
URL :
タイトル:
Re^2: ビット演算Andについて[解決]
早々にご回答いただいてありがとうございます。
丁寧な説明で納得できました。

当方MSのMSDN Onlineのみを参考にしてコーディングしているため、
基本的な部分を見つけるのに非常に手間取っております。
もしご存じであれば、
いただいた情報などが載っているサイトを
教えていただけないでしょうか。

少しずつ時間をとって探しているのですが、
明示的に色々と宣言する方法がわかるサイトを見つけられずにいます。
他の方々もご存知であれば、お教えください。

投稿時間:2003/04/23(Wed) 15:41
投稿者名:よねKEN
Eメール:
URL :http://www5b.biglobe.ne.jp/~yone-ken/
タイトル:
Re^2: ビット演算Andについて
> > Const A = &H00008000
> > Const B = &H00010000
> > Const C = &H00020000
> > Const D = &H00040000
>
> ↑ここを↓のように記述してください。
>
> Const A As Long = &H00008000&
> Const B As Long = &H00010000&
> Const C As Long = &H00020000&
> Const D As Long = &H00040000&

VBScriptだとAs 〜も型指定子も使えないはずです。
上記の16進数に対応する値の10進数で定数を切っておき、
実際にビット演算に使う際に、CLng関数でLong型にする必要があるのではないでしょうか。

下記のURLは以前、VBScriptをやったときに書いたメモです。参考までに。
http://www5b.biglobe.ne.jp/~yone-ken/VB/diff_vbs.html

また、元投稿のコードでは、
>  If ((a And A) = A) Then

というふうに、aとAを使ってらっしゃいますが、VB(やVBS)では、大文字、小文字の区別をしないのでまずいです。
ここに提示したものではない実際のソースコードではきっと別の変数を使われていて問題ないのだと思いますが、念のため。

投稿時間:2003/04/23(Wed) 16:16
投稿者名:birth
Eメール:
URL :
タイトル:
Re^3: ビット演算Andについて
> > Const A As Long = &H00008000&
> > Const B As Long = &H00010000&
> > Const C As Long = &H00020000&
> > Const D As Long = &H00040000&
> > ↑ここを↓のように
Const A = &H00008000&
Const B = &H00010000&
Const C = &H00020000&
Const D = &H00040000&

指摘いただいた内容ですが、
上記の通り変更することで対応できました。

> 下記のURLは以前、VBScriptをやったときに書いたメモです。参考までに。
> http://www5b.biglobe.ne.jp/~yone-ken/VB/diff_vbs.html
NullやEmptyの表現、数値の表現がわからないままでコーディングしています。
他にもご存知であれば、お教えください。
参考メモは、いただきます!
ありがとうございました。

投稿時間:2003/04/23(Wed) 17:21
投稿者名:nanashi
Eメール:
URL :
タイトル:
Re^3: ビット演算Andについて
> VBScriptだとAs 〜も型指定子も使えないはずです。

すいません、VBScriptは使ったこと無かったんですけど
だいたいVBと同じだろうと思って答えてました。
てゆーか、レス書いてる間にVBSであることなどすっかり忘れてました(汗)

投稿時間:2003/04/23(Wed) 22:59
投稿者名:NAO★
Eメール:
URL :
タイトル:
Re: ビット演算Andについて
> Function fLib(a,b)
>   If ((a And A) = A) Then
>     'bを使った処理1
>   End If
>   If ((a And B) = B) Then
>     'bを使った処理2
>   End If
>   If ((a And C) = C) Then
>     'bを使った処理3
>   End If
> End Function

質問とは関係ありませんが、条件式は
if a And A Then
という風に書けますよ

たとえば 変数の値を展開してみて
if &H00018000 And &H00008000 Then
となると結果は
if &h00008000 Then
となってTrue (正確にはFalse(0) 以外の値) になり条件が成立します

たとえば
if &H00040000 And &H00008000 Then
だった場合には
if 0 Then
となってFalse(0) になります。

ご参考までに

投稿時間:2003/04/24(Thu) 10:05
投稿者名:よねKEN
Eメール:
URL :
タイトル:
Re^2: ビット演算Andについて
> > Function fLib(a,b)
> >   If ((a And A) = A) Then
> >     'bを使った処理1
> >   End If
> >   If ((a And B) = B) Then
> >     'bを使った処理2
> >   End If
> >   If ((a And C) = C) Then
> >     'bを使った処理3
> >   End If
> > End Function
>
> 質問とは関係ありませんが、条件式は
> if a And A Then
> という風に書けますよ

If (a And A) <> 0 Then

個人的には、「<> 0」という比較を付けた方がビット演算を意図していることが明確になるのでいいと思いますし、
ビット演算の条件式を複数Andでつなぐ場合「<>0」を付けていないとまずかったりします。

「=A」ではなく「<> 0」とする記述法のメリットは、NAO★さんの記述と同様ですが、
Aという情報を2回書かずに済むので、ソースコードの変更時の修正量も抑えられる点にあります。

投稿時間:2003/04/24(Thu) 10:30
投稿者名:birth
Eメール:
URL :
タイトル:
Re^3: ビット演算Andについて
"If a And A Then"
この記述でも同様の処理になることは把握していましたが、
「aでAの時」と思われたくなかったため(ビット演算を意識してもらうため)
"If (a And A) = A Then"
の記述にしていました。
設計フェーズなし、ルール無用、でコーディングさせられているところなので、
色々戸惑いながらやってます。。。

> If (a And A) <> 0 Then
確かにこの記述が一番スマートかもしれませんね。
自分でも
"If (a And A) = A Then"
Aが2回登場するのが煩わしかったものですから。