MODBUS TCP 答案转换为浮点型 C++

发布于 2024-12-08 19:39:36 字数 829 浏览 0 评论 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);
}

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

I got a Problem. I've got a MODBUS TCP answer, which is hex coded like this: 0 0 0 0 0 7 1 4 4 41 B8 66 64. For explanation: the first five zeroes are a specification of Modbus, the 7 are the numbers of bytes following after it. the 1 is the client address in the Modbus network and not relevant. the first 4 is the function code which is used. the second 4 is again the numbers of bytes following. The last four bytes is the hex coded answer, which should be converted to double. The array, in which this is stored is a unsigned char array.
Here a few examples how i tried it.
Here the first example:

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

Value is the used double variable and ibuf the used char array.
Here the second one:

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);
}

Here I used a fixed value, but the problem is always the conversion from hex to double.
I'm glad about every help I could get.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

时间海 2024-12-15 19:39:36

你快到了。不幸的是,转换在升级期间自动发生 - 避免这种情况的最“直接”方法是通过取消引用 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'

You're almost there. Unfortunately, conversion occurs automatically during promotion - the most "straightforward" way of circumventing this is through dereferencing a float pointer cast of an int, as so:

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

For the data supplied, this gives 23.049995 instead of 1.1026039e+009, which you get from conversion.

EDIT:

As Mike Seymour pointed out in the comment below, a preferred way to write this is:

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

Note that you cannot do this:

float fval = reinterpret_cast<float>(ival);

This will raise an error (as seen here in VS2005):

error C2440: 'reinterpret_cast' : cannot convert from 'int' to 'float'
提笔落墨 2024-12-15 19:39:36

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

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

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

I would use an bitwise or operator to recreate the floating point value.

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

This code assumes that unsigned int has a size of four bytes on your platform.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文