我在从 Arduino 切换到 Unity 时遇到问题;本质上,我正在用 C++ (Arduino) 构建一个有效载荷结构,并使用以下串行协议(protocol)将其发送到 PC:
1 字节 - header
1 字节 - 负载大小
X 字节 - 负载
1 字节 - 校验和 (LRC)
有效负载如下所示:
struct SamplePayload {
double A;
double B;
double C;
double D;
} payload;
当我 sizeof(payload) 我得到 16 字节时,当我认为 double 是 8 字节数据类型时;如果我添加另一个 double 结构是 20 个字节,依此类推。我误会了什么吗?这导致了问题,因为它随后被转换为字节数据流并在 C# 中转换为接收到的结构,而且我不确定等效的数据类型是什么(转换为 double 会给出错误的值)。 Unity 中的串行协议(protocol)还依赖于正确的负载大小来读出流。
这可能是一个简单的答案,但我在任何地方都找不到,非常感谢!
最佳答案
如果您的应用程序对数字不敏感,您可以使用以下方法:
您可以使用两个 int32_t
而不是在您的结构中使用 double (如评论中所述,这不是严格标准化的)。 , a
和 b
代表一个重要的指数,这样
a*2^b = original_double
所以你的结构看起来像这样:
struct SamplePayload {
int32_t A_sig;
int32_t A_exp;
//B,C...
} payload;
然后在接收方,你只需要按照上面的公式相乘就可以得到原来的double。
C 为您提供了一个简洁的函数, frexp
,让事情变得简单。
但是因为我们同时存储了 a
和 b
作为整数,我们需要稍微修改结果以获得高精度。
具体来说,自 a
保证在0.5到1之间,需要乘以a
乘以 2^30,然后从 b
中减去 30为了不溢出。
这是一个例子:
#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;
}
关于c# - C++ 中的结构大小 & 转换为 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50629966/