将uint8_t数组转换为uint16_t

3

我有一个包含两个元素的 uint8_t 数组:

uint8_t ui8[2]; // uint8_t array
ui8[0] = 70; // LSB
ui1[1] = 60; // MSB

我想从这两个uint8_t值中获取一个uint16_t数字(而不是数组)。为了得到这个结果,我使用了以下方法:

uint16_t ui16 = 6070
uint16_t ui16 = ui8[1] | (ui8[0] << 8);

但我得到了 uint16_t ui16 = 15430;

我使用的方法是错误的吗?还是有什么东西缺失了?


你为什么会得到6070(或者应该是7060)?100从哪里来的? - Biffen
@Biffen 我不明白为什么应该是7060?假设我有一个数字6070,它是uint16_t类型的,但我需要将它复制到另一个变量中,但我只有一个接受uint8_t类型的函数。在这种情况下我该怎么办?我的想法是创建一个包含两个元素的数组:70和60,然后将它们附加在一起以获取uint16_t值。 - Pryda
3
60乘以256再加上70等于15430。 - Mike
@zerocoldTUN,我认为7060是因为你在ui8[0]中有70,在ui8[1]中有60,但无论如何,似乎你想使用小端。然而仍然不清楚的是,为什么你想进行十进制运算。如果你将8位值视为16位值的二进制“半部分”,那么60和70“连接”起来就变成了15430。 - Biffen
3个回答

7
也许您想要使用十六进制数操作:
uint8_t ui8[2]; // uint8_t array
ui8[0] = 0x70; // LSB
ui1[1] = 0x60; // MSB

uint16_t ui16 = ui8[1] | (ui8[0] << 8);
printf("%x\n", ui16); // 7060

如果你想使用十进制数,那么当你需要将“MSB”乘以100再相加。但是在这种情况下使用十进制的情况较少。

uint8_t ui8[2]; // uint8_t array
ui8[0] = 70; // LSB
ui1[1] = 60; // MSB

uint16_t ui16 = ui8[1] + (ui8[0] * 100);
printf("%d\n", ui16); // 7060

请注意,在这两种情况下,"70"都在"60"之前,因为你正在移动数组的第一个元素(70),70将是最高位。

4
请注意,代码在进行移位操作之前应将uint8_t值强制转换为uint16_t类型。否则,一个uint8_t类型的值会被提升为int类型,可能是16位的,这种情况下移位可能会发生溢出,导致未定义的行为。 - Eric Postpischil

5
你也可以使用联合体来实现它:
#include <stdio.h>
#include <stdint.h>

typedef union {
    uint8_t u8[2];
    uint16_t u16;
}data16;

int main() {
    data16 d16;

    d16.u8[0] = 0x60;
    d16.u8[1] = 0x70;

    printf("%hx\n", d16.u16);

    // it works in the opposite direction as well
    // lets try to store 7060 decimal in two bytes

    d16.u16 = 7060u;

    printf("storing %hu decimal in two bytes: LSB:0x%0hhx (%hhu decimal), MSB:0x%0hhx (%hhu decimal)\n", d16.u16, d16.u8[0], d16.u8[0], d16.u8[1], d16.u8[1]);

    return 0; }

1
uint8_t ui8[2]; // uint8_t array
ui8[0] = 70; // LSB
ui1[1] = 60; // MSB

要将这两个值复制到uint16中,可以按以下方式执行:
uint16_t output = 0;
output |= (uint16_t)ui8[0] << 8;
output |= (uint16_t)ui8[1] << 0;

你可以使用类似的逻辑,从 uint8_t 数组中写入 uint32_t/uint64_t。

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