c# - C++ 中的结构体大小 & 转换为 C#
问题描述
我在从 Arduino 到 Unity 工作时遇到问题;本质上,我正在 C++ (Arduino) 中构建一个有效负载结构,并使用以下串行协议将其发送到 PC:
1 字节 - 标头
1 字节 - 有效载荷大小
X 字节 - 有效载荷
1 字节 - 校验和 (LRC)
有效载荷如下所示:
struct SamplePayload {
double A;
double B;
double C;
double D;
} payload;
当我 sizeof(payload) 得到 16 个字节时,当我相信 double 是 8 字节数据类型时;如果我添加另一个双倍结构是 20 个字节,依此类推。我是不是误会了什么?这导致了问题,因为它随后被转换为字节数据流并在 C# 中接收时转换为结构,我不确定等效的数据类型是什么(转换为双精度值会给出错误的值)。Unity 中的串行协议还依赖于正确的有效负载大小来读取流。
这可能是一个简单的答案,但我在任何地方都找不到,非常感谢!
解决方案
如果您的应用程序对数字不敏感,则可以使用以下方法:
而不是在你的结构中使用双精度数(这不是严格标准化的,如评论中所述),你可以使用 two int32_t
, a
andb
来表示一个重要的和一个指数,这样
a*2^b = original_double
所以你的结构看起来像这样:
struct SamplePayload {
int32_t A_sig;
int32_t A_exp;
//B,C...
} payload;
然后在接收方,您只需根据上面的公式乘以得到原始的双倍。
C 为您提供了一个简洁的函数frexp
, 来简化事情。
但是由于我们将a
和都存储b
为整数,因此我们需要稍微修改结果以获得高精度。
具体来说,由于a
保证在 0.5 和 1 之间,因此您需要乘以a
2^30,然后再减去 30 b
,以免溢出。
这是一个例子:
#include <stdio.h> /* printf */
#include <math.h> /* frexp */
#include <stdint.h>
int main ()
{
double param, result;
int32_t a,b;
param = +235.0123123;
result = frexp (param , &b);
a=(result*(1<<30)) /*2^30*/; b-=30;
printf ("%f = %d * 2^%d\n", param, a, b); //235.012312 = 985713081 * 2^-22
return 0;
}
推荐阅读
- excel - 从 XMLHTTP 请求下载 Excel 文件,而不是打开 IE 并使用 IUIAutomation
- php - 从刀片中的按钮运行 Laravel 功能
- matlab - 如何使用掩码编辑器中的对话框进行不断更改?
- asp.net-core - 缺少类型映射配置或不支持的映射。用于 DTO 的集合
- google-maps - 在谷歌地图上创建多条不同颜色的堆叠折线
- java - isDebuggerConnected() 是做什么用的?
- javascript - “文件”参数必须是字符串类型。在 npm 运行部署到 gh-pages 时收到未定义的类型
- javascript - 即使在 QuickRex 中匹配,也无法匹配 JavaScript 中的 RegExp
- css - 将类属性应用于 Angular 组件元素是不好的做法吗?
- python-3.x - base64解码和写入图像/python3/必须是str,而不是字节