初めて質問させていただきます。
VB 5.0です。
バイナリ配列から2バイトを数値として読みたいのですが、
うまくいきません。
Dim aa(1) As Byte
Dim n As Integer
aa(0) = &HFF
aa(1) = &HFF
n = Val("&H" & aa(0) & aa(1))
この時、n = 65535 となるようにしたいのですが、
n = -1 となってしまいます。
どのようにすれば良いのでしょうか。
ご教授願います。
Integer は-32768〜32767しか表せないから65535は範囲外です。
「Dim n As Long」でどうですか?(環境ないから未確認)
GODさん
回答ありがとうございます。
longで試してみましたが、n = 2445909 になってしまいます。
>>> aa(0) = &HFF
これは、
aa(0) = 255
と同義である事に注意してください。
10進数で表記しようと、16進数で表記しようと、
それが指し示す値は同じ数値を意味します。
そして、それに続く
n = Val("&H" & aa(0) & aa(1))
という処理は、結局のところ
n = Val("&H" & CStr(255) & CStr(255))
として扱われることになります。ゆえに、この Val 関数は
n = &H255255
として処理され、「n = 2445909」という値になります。
>> 「Dim n As Long」でどうですか?
Debug.Print CInt("&HFFFF") '-1
Debug.Print CLng("&HFFFF") '65535
になりますね。
> n = 65535 となるようにしたいのですが、
例えば、
Dim aa(1) As Byte
aa(0) = &HFF
aa(1) = &HFF
n = aa(0) * &H100& + aa(1)
のようにすれば OK です。もし、"FF" という16進数表記からの変換を求めるなら
Dim aa(1) As String
aa(0) = "FF"
aa(1) = "FF"
n = CLng("&H" & aa(0) & aa(1))
とか、
Dim aa(1) As Byte
aa(0) = &HFF
aa(1) = &HFF
n = CLng("&H" & Hex(aa(0)) & Hex(aa(1)))
のように記述すれば OK かと。
やっと発掘に成功しました。(VB6だけどw)
魔界の仮面弁士 さんフォローありがとうございます。
私は別アプローチということでValを使ったやり方を。
n = Val("&H" & Hex(bytBuf(0)) & Hex(bytBuf(1)) & "&")
↑のように16進文字に変換結合後、最後に"&"をつけてLong型であることを
明示すればご希望の動作になりますよ。(最後に"&"を連結しないと-1になりま
す。)
質問が気になって調べていたら、
既にGODさん、魔界の魔界の仮面弁士 さんから良回答がっ!
1つ気になった点をば。
魔界の仮面弁士さんの回答にあります
n = CLng("&H" & Hex(aa(0)) & Hex(aa(1)))
は aa(1) が &HFF 固定(もしくは16進数2桁)時に有効です。
仮に aa(1) が &H1 〜 &HF になる可能性がある場合、
16進数の10の位を考慮しないと仕様によっては
いけないかもしれません。
考慮するのであれば
n = CLng("&H" & Hex(aa(0)) & Right$("0" & Hex(aa(1)),2))
でよいかと思います。
例えば、aa(0) = &H10 , aa(1) = &H1 の場合
CLng("&H" & Hex(aa(0)) & Hex(aa(1))) → &H101 → 257
CLng("&H" & Hex(aa(0)) & Right$("0" & Hex(aa(1)),2))
→ &H1001 → 4097
となります。
先に書きましたが、仕様上「257にしたい」となれば
魔界の仮面弁士さんの回答が正しいことになります。
希望する仕様で使い分けてください。
余談
GODさんの回答の補足説明
◆ & を付与しない場合 → Integer 型で処理されます
&H1 〜 &H7FFF → 1 〜 32767
&H8000 〜 &FFFF → -32768 〜 -1
となります。最上位桁が8〜Fの場合は負の整数として扱われます。
もうおわかりでしょうが、n = -1となった理由はこれです。
◆ & を付与した場合 → Long 型で処理されます
&H1 〜 &H7FFFFFFF → 1 〜 2147483647
&H80000000 〜 &FFFFFFFF → -2147483648 〜 -1
となります。こちらも最上位桁が8〜Fの場合は
負の整数として扱われます。
以上
> 仮に aa(1) が &H1 〜 &HF になる可能性がある場合、
> 16進数の10の位を考慮しないと仕様によっては
おお、うっかりしていました。フォロー感謝。
> &H1 〜 &H7FFFFFFF → 1 〜 2147483647
> &H80000000 〜 &FFFFFFFF → -2147483648 〜 -1
ちなみに oleaut32.dll のバージョンによって、より長い桁数の16進数値も扱えるようです。
どのバージョンでも問題なく使えるのは、8桁まで(Long型の上限)のようですけれども。
Debug.Print CDec("&H7FFFFFFFFFFFFFFD") ' 9223372036854775805
Debug.Print CDec("&H7FFFFFFFFFFFFFFE") ' 9223372036854775806
Debug.Print CDec("&H7FFFFFFFFFFFFFFF") ' 9223372036854775807
Debug.Print CDec("&H8000000000000000") '-9223372036854775808
Debug.Print CDec("&H8000000000000001") '-9223372036854775807
Debug.Print CDec("&H8000000000000002") '-9223372036854775806
' :
Debug.Print CDec("&HFFFFFFFFFFFFFFFD") '-3
Debug.Print CDec("&HFFFFFFFFFFFFFFFE") '-2
Debug.Print CDec("&HFFFFFFFFFFFFFFFF") '-1
遅くなってしまい、大変申し訳ありません。
GODさん、魔界の仮面弁士さん、しんごさん
どうもありがとうございました。
とても勉強になりました。
これからもよろしくお願いします。
ツイート | ![]() |