c++ - 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);
谁能在这里给我一个先机?
解决方案
您的编码方法可以只是一个作业。无符号整数类型和有符号整数类型之间的隐式转换是明确定义的。
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);
}
如需进一步了解位操作机制,您可以查看此处。
推荐阅读
- vba - 如何比较和突出一列中的字符串列表与excel中的另一列
- c# - 尝试将数据从actionmethod发送到mvc中的静态方法
- html - 如何避免框在悬停时移动?
- android - 我无法使用 Firebase 身份验证通过电子邮件和密码登录
- android - 从 Firebase 存储中删除图像时出错
- javascript - 如何附加由于函数而创建的元素?
- angular - angular 4 rerouting-component 不会重新加载
- php - 使用 .htaccess 删除 .php 扩展名会重复我的页面吗?
- ios - 如何使用 UITableView 在列表中创建列表
- python - 将列表从 pandas 列附加到 python 列表