新・Webパンくず

とりとめのない日記とか備忘録とか
2017/10 | 12345678910111213141516171819202122232425262728293031
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
するとか言ってシフト演算の話以降ブログには何も書いていなかったことに気づく。

符号無しの型が無いVBでシフト演算をしようと思うと、意外と面倒なことに気づく。
ビットのシフト自体はひとつ大きな型(Integer なら Long に)にキャストしてから行えば問題は無い。
問題はシフト後の数値を元の型に戻すときで、このとき先頭ビットが立っている数値(たとえば&H8000)を戻そうと思うと、この数値は Long 型では10進数で 32768 だが integer 型にはこの数値は入らずにオーバーフローエラーが起きる。Integer 型では10進数で -32768 が &H8000 になるからだ。

先頭ビットの状態を見て適宜型に応じた10進数に読み替えてから、ひとつ小さい型に戻してやる、という処理を書けばよい訳だが、何となく面倒だしかっこ悪いし何より納得いかない。
メモリ状態をそのまま移せば済むだけのところを、えらく回りくどい。仕方が無いので、下のような形で無理やり解決する。(左シフトね)



Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Public Function Int_L_Shift(ByVal Data%, ByVal BitCount%) As Integer

  Dim nVar&
  Dim ret%

  If BitCount >= 16 Then
    ret = 0
  ElseIf BitCount < 0 Then
    ret = Data
  ElseIf BitCount = 0 Then
    ret = Data
  Else
    nVar = Data * (2 ^ BitCount)
    Call CopyMemory(ret, nVar, 2)
  End If

  Int_L_Shift = ret

End Function



API を使って無理やりメモリ内容をコピーしています。
Long 型の下位2バイトのメモリを Integer型 に押し込んでます。
こういうやり方が作法として認められるものかどうか定かでは無いのですが、とりあえずきちんと動けばよしとする。これぞ俺竜。
右シフトも同じような感じでAPIで戻す。詳細はいちいち書きませんが。

実際の移植は結構進んでまして、いくつかのマッパー(0~4)は吸いだせるようになってきました。
もうちょっと形がしっかりしてきたら本店にも乗せてみたいと思います。

以上、プログラムに興味ない人にはさっぱりわからない話でした。
スポンサーサイト
コメント
この記事へのコメント
コメントを投稿する
URL:
Comment:
Pass:
秘密: 管理者にだけ表示を許可する
 
トラックバック
この記事のトラックバックURL
http://color12345.blog114.fc2.com/tb.php/40-e674632c
この記事にトラックバックする(FC2ブログユーザー)
この記事へのトラックバック
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。