0

我有一个问题。我有一个 MODBUS TCP 答案,它的十六进制编码如下:0 0 0 0 0 7 1 4 4 41 B8 66 64。为了解释:前五个零是 Modbus 的规范,7 是字节数紧随其后。1 是 Modbus 网络中的客户端地址,不相关。前4个是使用的功能代码。第二个 4 再次是后面的字节数。最后四个字节是十六进制编码的答案,应转换为双精度。存储它的数组是一个无符号字符数组。这里有几个例子我是如何尝试的。这里是第一个例子:

value = (ibuf[9]<<24) + (ibuf[10]<<16) + (ibuf[11]<<8) + ibuf[12];

Value 是使用的 double 变量,ibuf 是使用的 char 数组。这里是第二个:

for(i = 0; i < k; i++)
{
    if (i==0)
    {
        sprintf(ergebnis, "%x%x", ibuf[9], ibuf[10]);
    }
    else
    {
        //sprintf(buffer,"%x%x",ibuf[9+i+i], ibuf[10+i+i]);
        //strcat( ergebnis, buffer );
        sprintf(ergebnis, "0x41b451e8");
        sscanf(ergebnis, "%l %lf ", &Value);
    }
    printf("Ergebnis %s\n", ergebnis);
}

这里我使用了一个固定值,但问题始终是从十六进制到双精度的转换。我很高兴我能得到每一个帮助。

4

2 回答 2

2

您快到了。不幸的是,转换在提升过程中自动发生 - 最“直接”的规避方法是通过取消引用 int 的浮点指针转换,如下所示:

int ival = (ibuf[9]<<24)+(ibuf[10]<<16)+(ibuf[11]<<8)+ibuf[12];
float fval = *(float*)&ival;

对于提供的数据,这给出了 23.049995 而不是 1.1026039e+009,这是您从转换中获得的。

编辑:

正如 Mike Seymour 在下面的评论中指出的那样,写这个的首选方式是:

float fval = *reinterpret_cast<float*>(&ival);

请注意,您不能这样做:

float fval = reinterpret_cast<float>(ival);

这将引发错误(如 VS2005 中所示):

error C2440: 'reinterpret_cast' : cannot convert from 'int' to 'float'
于 2011-10-10T15:39:44.260 回答
0

我会使用按位或运算符来重新创建浮点值。

unsigned int value = 0x00000000 | ibuf[9]  << 24
                                | ibuf[10] << 16
                                | ibuf[11] << 8
                                | ibuf[12];
float floatValue = (float)value;

此代码假定 unsigned int 在您的平台上具有四个字节的大小。

于 2011-10-10T15:41:22.503 回答