2016-08-04 7 views
2

32ビットの16進数(例:CEED6644)を4バイトに分解するにはどうすればよいですか(var1 = CE、var2 = ED、 var3 = 66、var4 = 44)。 QB64またはQBasicで。私はこれを使用して、複数のデータバイトを1つの配列アドレスに格納します。あなたはこれを実現するために、整数の除算(\)とビット単位のAND(AND)を使用することができ32ビットの16進数を4バイトに分割する[QB64]

DIM Array(&HFFFF&) AS _UNSIGNED LONG 
Array(&HAA00&) = &HCEED6644& 
addr = &HAA00& 
SUB PrintChar 
SHARED addr 

IF var1 = &HAA& THEN PRINT "A" 
IF var1 = &HBB& THEN PRINT "B" 
IF var1 = &HCC& THEN PRINT "C" 
IF var1 = &HDD& THEN PRINT "D" 
IF var1 = &HEE& THEN PRINT "E" 
IF var1 = &HFF& THEN PRINT "F" 
IF var1 = &H00& THEN PRINT "G" 
IF var1 = &H11& THEN PRINT "H" 

のように...

答えて

2

:このような 何か。あなたが代わりにシフトするビットであるあなたが本当に何をやっているので、代わりに生の整数の除算のジェネリックRShift~&機能を使用することができます

DIM x(0 TO 3) AS _UNSIGNED _BYTE 
a& = &HCEED6644& 
x(0) = (a& AND &HFF000000&) \ 2^24 
x(1) = (a& AND &H00FF0000&) \ 2^16 
x(2) = (a& AND &H0000FF00&) \ 2^8 
x(3) = a& AND &HFF& 
PRINT HEX$(x(0)); HEX$(x(1)); HEX$(x(2)); HEX$(x(3)) 

注:その時に

x(0) = RShift~&(a& AND &HFF000000&, 18) 
... 

FUNCTION RShift~& (value AS _UNSIGNED LONG, shiftCount AS _UNSIGNED BYTE) 
    ' Raise illegal function call if the shift count is greater than the width of the type. 
    ' If shiftCount is not _UNSIGNED, then you must also check that it isn't less than 0. 
    IF shiftCount > 32 THEN ERROR 5 
    RShift~& = value/2^shiftCount 
END FUNCTION 

ビルは、あなたが別の関数を作成することがあります: (2の累乗による乗算)左にビットシフトLShift~&関数を使用したこと

FUNCTION ByteAt~%% (value AS _UNSIGNED LONG, position AS _UNSIGNED BYTE) 
    'position must be in the range [0, 3]. 
    IF (position AND 3) <> position THEN ERROR 5 
    ByteAt~%% = RShift~&(value AND LShift~&(&HFF&, 8*position), 8*position) 
END FUNCTION 

注意。潜在的により良い代替手段がLShift~&の必要性を排除する、第1の右シフトを実行し、単に下位8ビットをマスクすることであろう。

FUNCTION ByteAt~%% (value AS _UNSIGNED LONG, position AS _UNSIGNED BYTE) 
    'position must be in the range [0, 3]. 
    IF (position AND 3) <> position THEN ERROR 5 
    ByteAt~%% = RShift~&(value, 8*position) AND 255 
END FUNCTION 

なお、FreeBASICのとして知られている別のQBのような実装は、実際SHRオペレータを有する

、潜在的により速い除算を使用する代わりに直接シフト演算を実行するために MODまたは ANDのように使用されます。

ます。また、シフト操作を実行しますC++で関数を作成するQB64の DECLARE LIBRARY機能を使用することができます

/* 
* Place in a separate "shift.h" file or something. 
*/ 
unsigned int LShift (unsigned int n, unsigned char count) 
{ 
    return n << count; 
} 

unsigned int RShift (unsigned int n, unsigned char count) 
{ 
    return n >> count; 
} 

ここでフル対応QB64コードです:QB64は文書化されたAPIを持っていた場合

DECLARE LIBRARY "shift" 
    FUNCTION LShift~& (value AS _UNSIGNED LONG, shiftCount AS _UNSIGNED _BYTE) 
    FUNCTION RShift~& (value AS _UNSIGNED LONG, shiftCount AS _UNSIGNED _BYTE) 
END DECLARE 

x(0) = ByteAt~%%(a&, 0) 
x(1) = ByteAt~%%(a&, 1) 
x(2) = ByteAt~%%(a&, 2) 
x(3) = ByteAt~%%(a&, 3) 
END 

FUNCTION ByteAt~%% (value AS _UNSIGNED LONG, position AS _UNSIGNED BYTE) 
    'position must be in the range [0, 3]. 
    IF (position AND 3) <> position THEN ERROR 5 
    ByteAt~%% = RShift~&(value, 8*position) AND 255 
END FUNCTION 

シフト・カウントが高すぎる場合、C++の動作に頼ってシフト・カウントを無視するのではなく、C++コードからQB64エラーを発生させる可能性があります。残念ながら、これは当てはまらず、実際には価値があるよりも多くの問題を引き起こす可能性があります。

+0

ああ、ありがとうございます!それはおそらく私の人生で見た最も詳細な答えでした! – Aureal

0

このスニップは、16進数の値のバイトのペアを取得します。

DIM Value AS _UNSIGNED LONG 
Value = &HCEED6644& 
S$ = RIGHT$("00000000" + HEX$(Value), 8) 
PRINT "Byte#1: "; MID$(S$, 1, 2) 
PRINT "Byte#2: "; MID$(S$, 3, 2) 
PRINT "Byte#3: "; MID$(S$, 5, 2) 
PRINT "Byte#4: "; MID$(S$, 7, 2) 
関連する問題