• ベストアンサー

マスクをとるとオーバーフローします

VBで4byteの数字の上位2バイト、下位2バイトをとりだす方法を教えてください。 以下のコードの8行目で(9行目も同様)オーバーフローしてしまいます。 1 Dim inputData As Double 2 3 Dim d1 As Double 4 Dim d2 As Double 5 6 inputData = 65538 'd1=1, d2=2を期待 7 d1 = inputData And 65535 'FFFFでマスク 8' d2 = inputData And 4294901760# 'FFFF0000でマスク 9 d2 = CDbl(inputData And 4294901760#) 'FFFF0000でマスク

質問者が選んだベストアンサー

  • ベストアンサー
  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.4

ようは、32bit符号なし数値を、上位16bitと下位16bitに切り出して符号なしの数値で求めたいということですよね。 Dim inputData As Long Dim d1 As Long Dim d2 As Long inputData = &HFFFFFFF0 '上位と下位がわからなくなるとまずいので変えてあります。 d1 = inputData And &HFFFF& Dim str As String str = "00000000" & Hex(inputData And &HFFFF0000) d2 = "&H" & Left(str, Len(str) - 4) MsgBox d1 & " " & d2 あとはマスクではなくこんな方法も。 Type typeL l As Long End Type Type typeI iL As Integer iH As Integer End Type Sub Main() Dim l As typeL Dim i As typeI Dim d1 As Long Dim d2 As Long l.l = &HFFFFFFF0 LSet i = l d1 = "&H" & Hex(i.iL) d2 = "&H" & Hex(i.iH) MsgBox d1 & " " & d2 End Sub

yumi-mika
質問者

お礼

ありがとうございました。 いろんな解法があるんですね。 Typeははじめてみました。 ありがとうございました。

その他の回答 (3)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

こんな感じでどうでしょう? Dim inpData As Long Dim d1 As Long Dim d2 As Long Dim dh 'inpData = &HFFFFFFFF inpData = 65538 dh = Right("00000000" & Hex(inpData), 8) d1 = Val("&H" & Left(dh, 4)) d2 = Val("&H" & Right(dh, 4)) If d1 < 0 Then d1 = d1 + 65536 If d2 < 0 Then d2 = d2 + 65536 'Debug.Print d1 'Debug.Print d2

yumi-mika
質問者

お礼

String型を介するんですねぇ! "00000000"をつけるのもポイントですね。 目から鱗です。勉強になりました。 ありがとうございました。

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.2

>説明不足でしたが、4byteというのは、符号なし4byteのことなのです。 符号はあってもなくてもビット操作をするのなら関係ないです。Double等のサイズが違うものを使用するほうがよっぽど問題です。 >inputDataに&FFFFFFFFを代入した時点でオーバーフローしてしまいます。 16進数にすればオーバーフローしません。 で、&FFFFFFFFではなく&HFFFFFFFFです。 #VB6で確認してます。 で、やりたいことってなんですか? >d1=65535 >d2=65535 >を取得したいのです。 下位16bitを符号なし整数で取得したいのでしょうか?そうすると、今度はd1とd2の違いがわからないのですが。

yumi-mika
質問者

補足

>16進数にすればオーバーフローしません。 そうだったんですね。下手に10進に直して代入したのが間違いの基でした。 >#VB6で確認してます。 お時間割いていただき感謝してます >>d1=65535 >>d2=65535 >>を取得したいのです。 > >下位16bitを符号なし整数で取得したいのでしょうか?そうすると、今度はd1とd2の違いがわからないのですが。 補足は、MAX(&HFFFFFFFF)を例にあげてしまったので、d1とd2が同じ値になりますが、 &H00010002の場合に、 d1=2(下位2バイト) d2=1(上位2バイト) となることを期待しています。 >で、d2って、2じゃなくて&H00010000ですよね? ではありません。&H0001です。 &HFFFFFFFFの場合には、d2に-65536ではなく d1=65535(下位2バイト) d2=65535(上位2バイト) となることを期待しています。

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.1

>6 inputData = 65538 'd1=1, d2=2を期待 おかしくありません?Doubleなんですよね。 浮動小数ですよ。こんなマスクのかけ方はだめですよね。 型はLongで、マスクは16進数で書きましょう。 また、&HFFFFだとInteger(16bit)になってしまうので、 &HFFFF&としてLong(32bit)にしましょう。 Dim inputData As Long Dim d1 As Long Dim d2 As Long d1 = inputData And &HFFFF& d2 = inputData And &HFFFF0000 で、d2って、2じゃなくて&H00010000ですよね?

yumi-mika
質問者

補足

ご指摘ありがとうございました。 説明不足でしたが、4byteというのは、符号なし4byteのことなのです。 最大、0xFFFFFFFFを10進で4294967295とみなして、 d1=65535 d2=65535 を取得したいのです。 なので、教えていただいた方法では inputDataに&FFFFFFFFを代入した時点でオーバーフローしてしまいます。 VBにはunsignedの型がないため、Doubleを使おうと考えました。 >で、d2って、2じゃなくて&H00010000ですよね? ご指摘どおり、d1とd2が逆でした。 求めたいのは上位2byteと下位2byteなので、最後にシフトしないとだめですね。

関連するQ&A

専門家に質問してみよう