【问题标题】:wrong conversion of two bytes array to short in c在c中将两个字节数组错误转换为short
【发布时间】:2019-03-23 04:35:58
【问题描述】:

我正在尝试将 2 字节数组转换为无符号短。

这是转换的代码:

short bytesToShort(char* bytesArr)
{
    short result =(short)((bytesArr[1] << 8)|bytesArr[0]);
    return result;
}

我有一个存储字节的 InputFile,我通过循环读取它的字节(每次 2 个字节)并以这种方式将其存储在 char N[] arr 中:

char N[3];
N[2]='\0';

while(fread(N,1,2,inputFile)==2)

(hex) 值 N[0]=0 时计算正确,否则计算错误,例如:

0x62 (N[0]=0x0,N[1]=0x62) 将返回 98(短值),但是 0x166 十六进制(N[0]=0x6,N[1 ]=0x16) 将返回 5638(简而言之)。

【问题讨论】:

  • 我强烈建议在这类游戏中使用无符号类型。
  • 这两件事可能会咬你是字节序和@EugeneSh 的符号扩展。暗示。
  • 请在您的问题/cmets 中使用特定于基础的前缀。不清楚您提到的66 是十六进制还是十进制。
  • 我会说它可以正常工作,因为 N[0]=0x06, N[1]=0x16 你得到 0x1606,你为什么期望它是 0x166? 0x166 表示 N[0]=0x66, N[1]=0x01
  • 0x166358。但是0x16065638。检查你的数学

标签: c


【解决方案1】:

首先,对于原始二进制数据的字节,通常最好使用 unsigned char 类型,因为这样可以正确表达您正在使用的内容的语义。键入char,虽然它可以而且经常被用作“字节”的同义词,但最好保留给实际上是字符的数据。

如果您还要对字节值执行算术运算,您几乎肯定需要unsigned char 而不是char,因为char 的符号是实现定义的。它确实因实现而异,并且在许多常见的实现中char签名

话虽如此,您的主要问题似乎很简单。你说

十六进制的 166 (N[0]=6,N[1]=16) 将返回 5638(简而言之)。

但是 0x166 打包到一个两字节的小端数组中将是 (N[0]=0x66,N[1]=0x1)。你写的对应0x1606,确实和十进制的5638是一样的。

【讨论】:

    【解决方案2】:

    问题是由于使用char而导致的符号扩展。您应该改用unsigned char

    #include <stdio.h>
    
    short bytesToShort(unsigned char* bytesArr)
    {
        short result = (short)((bytesArr[1] << 8) | bytesArr[0]);
        return result;
    }
    
    int main()
    {
        printf("%04x\n", bytesToShort("\x00\x11")); // expect 0x1100
        printf("%04x\n", bytesToShort("\x55\x11")); // expect 0x1155
        printf("%04x\n", bytesToShort("\xcc\xdd")); // expect 0xddcc
    
        return 0;
    }
    

    注意:代码中的问题不是OP提出的问题。问题是在输入 "\xcc\xdd" 时返回错误的结果。它将产生0xffcc,它应该是0xddcc

    【讨论】:

    • 虽然 OP 的代码 容易受到符号扩展引起的问题的影响(在签名 char 的实现上),但这并不是他们在他们的描述中描述的具体失败的原因问题。
    • 是的,但是在\xcc\xdd 的情况下,签名的字符版本产生了错误的结果。我检查了:)
    • 正如我已经规定的那样,尽管仅适用于签名char 的实现。这些很常见,所以你的就是其中之一也就不足为奇了。
    • 可能是这种情况,但这不是 OP 结果的原因,这是错误的期望而不是错误的代码(即使代码也是错误的)。您明确指出“问题是符号扩展...”,但这是一个不同的问题。
    猜你喜欢
    • 2011-08-10
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-15
    相关资源
    最近更新 更多