#include <stdio.h>
int main (void)
{
char highbyte = 0x01;
unsigned char lowbyte = 0xF4; //Edited as per comments from @Fe2O3,
short int val = 0;
val = (highbyte << 8) | lowbyte; // If lowbyte declared as signed, then masking is required `lowbyte & 0xFF`
printf("0x%hx\n", val);
return 0;
}
(uint16_t) highbyte << 8 | lowbyte转换为适合移位而不会出现符号位问题的类型,将较高有效字节移到16的高8位,并将较低有效字节放入低8位。 然后uint16_t = …;将这些位放入uint16_t。 memcpy(&result, &t, sizeof result); copies those bits into an int16_t . C 2018 7.20.1.1 1 guarantees that int16_t uses two’s complement. C 2018 6.2.6.2 2 guarantees that the value bits in int16_t have the same position values as their counterparts in uint16_t , so the copy produces the desired arrangement in result .
3条答案
按热度按时间polhcujo1#
我做了一些研究,我发现这是我的解决方案,它似乎工作得很好:
odopli942#
下面是一个基本的例子,说明如何将两个不同变量的值合并为一个:
已在Linux PC上测试。
qzlgjiam3#
根据转换为short的答案,您可能希望组合两个字节以生成一个16位的二进制补码整数。此答案显示了如何通过三种方式来实现此目的,C标准完全定义了这三种方式的行为,以及第四种方式,这需要了解所使用的C实现。方法1和3也在C++中定义。
给定两个8位无符号字节,高有效字节在
highbyte
中,低有效字节在lowbyte
中,用于构造它们所表示的16位二进制补码值的四个选项为:1.按所需顺序组装字节并将其复制到
int16_t
:uint16_t t = (uint16_t) highbyte << 8 | lowbyte; int16_t result; memcpy(&result, &t, sizeof result);
.1.按所需顺序组装字节,并使用并集重新解释它们:
int16_t result = (union { uint16_t u; int16_t i; }) { (uint16_t) highbyte << 8 | lowbyte } .i;
.1.用算术方法构造结果:
int16_t result = ((highbyte ^ 128) - 128) * 256 + lowbyte;
.1.如果给定代码将仅与定义转换为要 Package 的有符号整数的C实现一起使用,则可以使用转换:
int16_t result = (int16_t) ((uint16_t) highbyte << 8 | lowbyte);
.(In最后一种是,到
int16_t
的转换在初始化中是隐式的,但是使用了强制类型转换,因为如果没有强制类型转换,某些编译器将根据开关产生警告或错误。)注意:
int16_t
和uint16_t
是通过包含<stdint.h>
来定义的,或者,如果short
是16位,则可以使用short
和unsigned short
来代替int16_t
和uint16_t
。以下是有关前三个方面的详细信息。
1.组装字节并复制
(uint16_t) highbyte << 8 | lowbyte
转换为适合移位而不会出现符号位问题的类型,将较高有效字节移到16的高8位,并将较低有效字节放入低8位。然后
uint16_t = …;
将这些位放入uint16_t
。memcpy(&result, &t, sizeof result);
copies those bits into anint16_t
. C 2018 7.20.1.1 1 guarantees thatint16_t
uses two’s complement. C 2018 6.2.6.2 2 guarantees that the value bits inint16_t
have the same position values as their counterparts inuint16_t
, so the copy produces the desired arrangement inresult
.2.组合字节并使用联合
(
type) {
initial value}
是一个 * 复合文本 *。(union { uint16_t u; int16_t i; }) { (uint16_t) highbyte << 8 | lowbyte }
生成一个联合复合文本,并将其u
成员初始化为具有上述值。然后.i
读取联合的i
成员,后者使用类型int16_t
重新解释位,它是如上所述的二进制补码。然后int16_t result = …;
将result
初始化为这个值。3.用算术方法构造结果
这里我们从高有效字节开始,将
highbyte
的8位解释为2的补码,在8位2的补码中,符号位表示0(如果它是off的话)和-128(如果它是on的话)。(例如,111111002作为无符号二进制表示128 + 64 + 32 + 16 + 8 + 4 = 252,但在二进制补码中,它是-128 + 64 + 32 + 16 + 8 + 4 = -4。)以
highbyte ^ 128) - 128
为例。如果第一位为off,^ 128
将其打开,这将使其无符号二进制含义增加128。然后- 128
减去128,产生净效果为零。如果第一位为on,^ 128
将其关闭。取消了无符号二进制的含义,然后- 128
给出了所需的值,这样(highbyte ^ 128) - 128
重新解释了第一位,如果它是off,则其值为0,如果是on,则为-128。然后
((highbyte ^ 128) - 128) * 256
把它移到16位的高有效字节(在int
类型中),+ lowbyte
把低有效字节放在低有效位置,当然int16_t result = …;
把result
初始化为这个计算值。