0

問題が発生しました。MODBUS TCPの回答があります。これは次のように16進数でコード化されています:0 0 0 0 0 7 1 4 4 41 B8 6664。説明:最初の5つのゼロはModbusの仕様であり、7はバイト数です。その後に続く。1はModbusネットワークのクライアントアドレスであり、関係ありません。最初の4つは、使用される機能コードです。2番目の4は、次のバイト数です。最後の4バイトは16進数でコード化された回答であり、doubleに変換する必要があります。これが格納されている配列は、unsignedchar配列です。ここに私がそれをどのように試したかのいくつかの例があります。ここに最初の例があります:

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

値は使用されるdouble変数であり、ibufは使用されるchar配列です。ここで2番目のもの:

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

ここでは固定値を使用しましたが、問題は常に16進数から2進数への変換です。私は私が得ることができるすべての助けについてうれしいです。

4

2 に答える 2

2

もうすぐです。残念ながら、変換は昇格中に自動的に行われます。これを回避する最も「簡単な」方法は、intのfloatポインターキャストを逆参照することです。

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

提供されたデータの場合、これにより、変換から得られる1.1026039e+009ではなく23.049995が得られます。

編集:

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;

このコードは、unsignedintのサイズがプラットフォーム上で4バイトであることを前提としています。

于 2011-10-10T15:41:22.503 に答える