我有一个16位(无符号短)块的列表,我从程序的另一个部分收到,我想写入一个二进制文件。我试图将这些拆分成8位字符,所以我设计了这个方法:
int blocks = 1;
unsigned short stuffToWrite[blocks];
stuffToWrite[0] = 0b0100101011110111;
int charsPerBlock = sizeof(unsigned short) / sizeof(char);
char charsToWrite[blocks * charsPerBlock];
for (int i = 0; i < blocks; i++) {
for (int j = 0; j < charsPerBlock; j++) {
charsToWrite[i*charsPerBlock+j] = (stuffToWrite[i] & ((((int) pow(2, sizeof(char)*8)-1) << ((charsPerBlock-1)*sizeof(char)*8)) >> (j*sizeof(char)*8))) >> ((charsPerBlock-j-1)*sizeof(char)*8);
// Testing line //
printf("%u = (%u & %u) >> %lu\n", charsToWrite[i*charsPerBlock+j], stuffToWrite[i], (((int) pow(2, sizeof(char)*8)-1) << ((charsPerBlock-1)*sizeof(char)*8)) >> j*sizeof(char)*8, (charsPerBlock-j-1)*sizeof(char)*8);
}
这看起来很复杂,但实际上并不复杂。我只是创建了一个8位掩码((int) pow(2, sizeof(char)*8)-1)
),将其移到第一位(<< ((charsPerBlock-1)*sizeof(char)*8))
),然后将其移回正确的位置(>> (j*sizeof(char)*8)))
)。然后将其与原始块一起移到AND
,并将其移回最低位,成为一个字符(>> ((charsPerBlock-j-1)*sizeof(char)*8)
)。
这对于第一个块来说很好,得到了74
或01001010
。但是,第二个块给了我一个非常大的错误数字。我不确定这里出了什么问题,因为我很确定我的方法工作得很好,所以我写了一个测试行来分解产生以下结果的步骤:
74 = (19191 & 65280) >> 8
4294967287 = (19191 & 255) >> 0
这显然是错误的。
我将感谢任何帮助识别错误和如何修复它(也如果有更好的方法来做到这一点)。
1条答案
按热度按时间v9tzhpje1#
这看起来很复杂,其实不然。
如果你只是想把数据序列化成字节,那么你所需要的就是:
不管传入数据的字节序如何,这种方法都有效,但它假定输出数据的最高有效字节在前。
类似地,对于32位数字,您可以使用
>> 24
、>> 16
、>> 8
和>> 0
。还请注意,当执行按位算术时,切勿使用以下类型:有符号类型、
char
、浮点。