首页 > 解决方案 > 2 个 int8_t 到 uint16_t 并返回

问题描述

我想在我的应用程序中支持一些串行设备。该设备与另一个程序一起使用,我想与该设备和该程序创建的保存文件进行交互。

然而,由于一些尚未发现的原因,奇怪的整数转换正在进行中。设备通过串行 USB 连接返回 uint8,程序将它们作为 int8 保存到一个文件中,当您读取文件时,您需要将 2 个 int8 组合成一个 uint16。

因此,在读取设备后写入保存文件时,我需要将 int8 转换为 uint8,导致任何高于 127 的值都被写入负数。

然后当我读取保存文件时,我需要将 2 个 int8 组合成一个 uint16。(所以将负值转换为正值,然后将它们粘在一起)

然后,当我从应用程序中保存到保存文件时,我需要将我的 uint16 拆分为 2 个 int8。

我需要想出“编码”、“组合”和“爆炸”功能

// When I read the device and write to the save file:
uint8_t val_1 = 255;
int8_t val_2 = encode(val_1);
REQUIRE(-1 == val_2);

// When I read from the save file to use it in my program.
int8_t val_1 = 7;
int8_t val_2 = -125;
uint16_t val_3 = combine(val_1, val_2);
REQUIRE(1923 == val_3);

// When I export data from my program to the device save-file
int8_t val_4;
int8_t val_5;
explode(val_3, &val_1, &val_2);
REQUIRE(7 == val_4);
REQUIRE(-125 == val_5);

谁能在这里给我一个先机?

标签: c++castinginteger

解决方案


您的编码方法可以只是一个作业。无符号整数类型和有符号整数类型之间的隐式转换是明确定义的。

uint8_t val_1 = 255;
int8_t val_2 = val_1;
REQUIRE(-1 == val_2);

至于 combine - 您需要将第一个值转换为 auint16_t以确保您有足够的可用位,然后将其向左位移 8 位。这会导致您的第一个值中的位构成新值的 8 个最高有效位(8 个最低有效位为零)。然后,您可以添加第二个值,这将设置 8 个最低有效位。

uint16_t combine(uint8_t a, uint8_t b) {
    return ((uint16_t)a << 8) + b;
}

Explode 将与此相反。您需要右移 8 位以获得第一个输出值,然后只需简单地分配即可获得最低 8 位。

void explode(uint16_t from, int8_t &to1, int8_t &to2) {
    // This gets the lowest 8 bits, and implicitly converts
    // from unsigned to signed
    to2 = from;

    // Move the 8 most significant bits to be the 8 least
    // significant bits, and then just assign as we did
    // for the other value
    to1 = (from >> 8);
}

作为一个完整的程序:

#include <iostream>
#include <cstdint>

using namespace std;

int8_t encode(uint8_t from) {
    // implicit conversion from unsigned to signed
    return from;
}

uint16_t combine(uint8_t a, uint8_t b) {
    return ((uint16_t)a << 8) + b;
}

void explode( uint16_t from, int8_t &to1, int8_t &to2 ) {
    to2 = from;
    to1 = (from >> 8);
}

int main() {
    uint8_t val_1 = 255;
    int8_t val_2 = encode(val_1);
    assert(-1 == val_2);

    // When I read from the save file to use it in my program.
    val_1 = 7;
    val_2 = -125;
    uint16_t val_3 = combine(val_1, val_2);
    assert(1923 == val_3);

    // When I export data from my program to the device save-file
    int8_t val_4;
    int8_t val_5;
    explode(val_3, val_4, val_5);
    assert(7 == val_4);
    assert(-125 == val_5);
}

如需进一步了解位操作机制,您可以查看此处。


推荐阅读