将32位十六进制值拆分为4个字节[QB64]
问题描述:
我想问一下,如何将32位十六进制(例如:CEED6644)拆分为4个字节(var1 = CE,var2 = ED, var3 = 66,var4 = 44)。在QB64或QBasic中。我会用它来将几个数据字节存储到一个数组地址中。 事情是这样的:将32位十六进制值拆分为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"
等等......
答
你可以使用整数除法(\
)和按位AND(AND
)做到这一点。
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))
需要注意的是,你可以选择使用一个通用RShift~&
函数,而不是原始整数除法,因为你真的做什么换挡位:
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
在该大厦,您可以创建另一个功能:
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~&
函数(由2的幂乘)转移位到左侧。一个潜在的更好的替代方法是首先执行右移,只是掩模的低8位,从而消除了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, 8*position) AND 255
END FUNCTION
顺便提及,另一种已知的作为FreeBASIC QB样实现具有实际SHR
操作者,像MOD
或AND
一样使用,以直接执行移位操作而不是使用可能更快的分割。
你也可以使用QB64的DECLARE LIBRARY
设施,以创建在C++中,将进行移位操作功能:
/*
* 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代码:
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
如果QB64已文档化的API当移位计数过高时,可能会从C++代码中引发QB64错误,而不是依赖C++的行为来实质上忽略太高的移位计数。不幸的是,事实并非如此,它可能会导致更多的问题而不是价值。
答
这剪断得到一个十六进制值的字节对:
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)
哦,谢谢!这可能是我见过的最详细的答案! – Aureal