有符号整数的字节序转换

4
我正在通过UDP接收大端数据并将其转换为小端。源代码说整数是有符号的,但当我交换有符号整数(特别是16位)的字节时,得到的值不真实。当我将它们作为无符号整数进行交换时,我得到了我期望的结果。我想源文件的文档可能是错误的,并且实际上发送的是无符号的16位整数。但这有什么关系呢?所有值都应该是正数,并且明显低于16位INT_MAX,因此溢出不应该成为问题。我唯一能想到的是:(1)文档是错误的,并且(2)在执行有符号的大小端交换时,我没有正确处理符号位。
我真的有两个问题:
1)当溢出不是问题时,读入有符号或无符号整数是否重要。
2)有符号和无符号值之间的大小端交换是否不同(即符号位需要以不同的方式处理)?
我认为有符号和无符号值的大小端转换看起来是相同的,例如对于16位value = value&0xff00 >> 8 | value&0x00ff << 8
谢谢

希望你有括号(如果是C语言)。 - Tony van der Peet
1个回答

13

在您的交换函数中,您遇到了符号扩展的问题。而不是这样做:

value & 0xff00 >> 8 | value & 0x00ff << 8

做这个:

((value >> 8) & 0x00ff) | ((value & 0x00ff) << 8)
问题在于,如果value是一个16位有符号值,则0xabcd >> 8的结果是0xffab。如果在有符号右移中最高位为1,则该位将保持为1。

最后,你应该使用ntohs()而不是自己编写此函数。


3
ntohs不是一个通用的C库函数,而是来自(BSD)socket库的函数。非常有用,但是为了获取字节序工具函数而拉入套接字库有点奇怪 :P - Chris Becke
3
如果你已经在进行UDP通信,使用套接字函数并不奇怪。 - Greg Hewgill
遗憾的是,ntohs函数族已经过时了,即使它们仍然常用且没有被记录为过时,因为它们不支持64位整数。如果您必须编写一个支持64位的函数,那么最好将其制作成模板并支持所有类型。 - UKMonkey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接