【问题标题】:How to Reverse a 16 bit Hex Value in C?如何在 C 中反转 16 位十六进制值?
【发布时间】:2020-03-16 12:02:51
【问题描述】:

我正在尝试反转我的压力数据值并将此反转结果存储在整数 uint16_t Pcounts 中。我找到了一个可以使用的宏,它似乎翻转了一些位,但没有翻转其他位。这是我的代码:

#define REV(X) ((X << 24) | (((X>>16)<<24)>>16) | (((X<<16)>>24)<<16) | (X>>24))

uint16_t PressureData;
uint16_t Pcounts;
Pcounts = REV(PressureData);

如果 PressureData = 0xAABB,我希望 Pcounts 为 0xBBAA。但是,结果是 0xBB00。

PressureData 是从传感器检测到的实时压力值。

【问题讨论】:

  • 为什么要移动 16 位和 24 位? 16 位值没有那么高的位。
  • @Someprogrammerdude 好地方!宏应该是:#define REV(X) ((X >16)>16) | (((X>8) >8))
  • 该宏用于反转 32 位 unsigned 整数中的四个 8 位字节。不应该期望它使用 16 位或有符号整数。对于 16 位,您可以使用#define Rev16(x) ((x) &gt;&gt; 8 | (x) &lt;&lt; 8),假设参数是一个 16 位无符号整数并且结果被立即分配或强制转换为一个 16 位无符号整数。 (如果不是,则需要屏蔽。)
  • 如果您的系统是 little-endian 并且您使用 big-endian 存储,那么您正在执行标准转换 - 从特定于主机的字节顺序更改为 network byte order。这通常是为了便携性。这很常见,POSIX 定义了为您执行此操作的函数:htons() 会将 uint16_t 从主机字节顺序转换为网络字节顺序,ntohs() 将采用网络(大端)uint16_t 并将其转换为当前主机字节顺序。

标签: c hex reverse microchip


【解决方案1】:

如果 PressureData = 0xAABB,我希望 Pcounts 为 0xBBAA。

让我们假设abcd,OP 想要cdab(字节交换)而不是dcba(半字节交换):

下面将字节反转为 32 位值。 @Some programmer dude

#define REV(X) ((X << 24) | (((X>>16)<<24)>>16) | (((X<<16)>>24)<<16) | (X>>24))

反转 16 位 无符号 值的字节。 @Eric(通知()关于X。)

#define REV16_A(X) (((X) << 8) | ((X)>>8))

更好的代码不会依赖符号,而是强制解决问题。

#define REV16_B(X) (((uint16_t)(X) << 8) | ((uint16_t)(X)>>8))

然而,我认为这里没有什么理由使用宏,而只是使用辅助函数。如果需要,请将其设为inline

uint16_t rev16(uint16_t x) {
  return (x << 8) | (x >>8);
}

此外,我希望翻转字节的愿望是一个 endian 问题。因此,如果移植了代码,则可能/可能不需要翻转字节。在这种情况下,硬件可能会以某个字节序呈现字节,该字节序可能/可能与代码的本机字节序不匹配。考虑一个辅助函数来处理它。

uint16_t endian_hw_to_native16(uint16_t x) {
  // endian sensitive code ...
}

【讨论】:

  • 出于某种原因,BSD's bswap16() C code 这样做:return ((x &lt;&lt; 8) &amp; 0xff00) | ((x &gt;&gt; 8) &amp; 0x00ff);
  • @AndrewHenle 如果u_int16_t 不是uint16_t,我看到的面具的唯一用处。
  • 你比我看到的更多。 :-)
【解决方案2】:

问题是你覆盖了一些位。

尝试使用函数而不是宏:

swapped = ((input>>8)&0x0f) | // move byte 1 to byte 0
           (input<<8)&0xf0)); // byte 0 to byte 1

【讨论】:

    猜你喜欢
    • 2016-11-28
    • 2018-07-26
    • 2021-11-26
    • 2011-02-19
    • 1970-01-01
    • 2022-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多