0

unsigned long を Float 単精度に変換する際に問題があります これが私の問題です

プログラムで浮動小数点で通信する必要がありますが、内部変数はすべて unsigned long です。そのため、すべてが同じ (unsigned long) のままになるように設計し、float をアプリケーションに渡す必要があると決めました。 float に変換して渡します。

したがって、すべての変数は、次のように IEEE 754 ビット ストリームを持ちます。

フロートコンバーター

私が従う手順:

  1. char配列で値を取得します
  2. ビットを取得して unsigned long にコピーします
  3. 関数呼び出しでデータを渡しながら、単精度浮動小数点型に型キャストします。

デバッガーでは、ステップ 1 と 2 で同じビット パターン (バッファー内) が表示されます。

ステップ 3 でも同じバイナリ パターンが表示されますが、値が float として解釈されません。

入力: 21.125

  1. バイナリ: 01000001101010010000000000000000
  2. 16 進数: 0x41a90000
  3. 10 進数: 1101594624

    Code:
    void ApplicationApi(void * DataPtr)
    {
    (*(float32*)((void*)DataPtr))= unsignedLong_val;
    }
    

アプリケーションの結果 DataPtr * DataPtr = 1.101594624 * e9

ここに何かが欠けていますか、それともタイプケースが機能しましたか?

4

2 に答える 2

0

an のバイトをunsigned longa として再解釈する標準的な C の方法floatは次のとおりです。

y = (union { unsigned long u; float f; }) { x } .f;

このコードは、共用体である複合リテラルを定義し、共用体を の値で初期化しxますunsigned long。次にf、共用体のメンバーであるにアクセスしfloatます。このfloat値は に割り当てられます。yこれは である必要がありfloatます。

したがって、 の宣言がApplicationApi同じままである必要があり、void *DataPtr渡される がfloatへのポインタを へのポインタに変換した結果であると仮定するとvoid、その定義は次のようになります。

void ApplicationApi(void *DataPtr)
{
    * (float32 *) DataPtr =(union { unsigned long u; float32 f; }) { unsignedLong_val } .f;
}

このコードに関する注意:

  • これunsigned longfloat32は、同じサイズが必要です。
  • unsignedLong_valがファイル スコープを持つことは望ましくありません。パラメータとして渡す方が望ましいでしょう。
  • DataPtr を として渡す必要があるというこのコード固有の理由はありませんvoid *。として渡すことができますfloat32 *

このコードに至るまでのコードに関する注意:

  • でバイトが組み立てられた方法には、unsigned longエンディアンの問題がある場合があります。
  • 現在まれな C 実装では、unsigned long任意のバイトを保持するために使用されないようにするトラップ値を持つ可能性があります。

C 標準とバイトの再解釈について:

  • ユニオンによるバイトの再解釈は、C 2011 (N1570) 6.5.2.3 3 の結果であり、.演算子とメンバー名を使用する式は名前付きメンバーの値を持つことを示しています。標準の注 95 は、これを使用してバイトを再解釈できることを示しています。
  • バイトを再解釈するためにサポートされているもう 1 つの方法は、6.3.2.3 に従って、ポインターを文字型へのポインターに変換し、新しいポインターを使用してバイトをコピーするmemcpyことです。
  • 6.3.2.3 7 は、文字型へのポインターに対してのみこの動作を定義します。他の型の場合、C 標準では通常、ポインターを別の型のポインターに変換し、結果を逆参照する動作は定義されていません。したがって、これを行うコードの動作は未定義です。テストで動作するように見えても、コンパイラの最適化やその他の影響により、後で失敗する可能性があります。
于 2013-08-22T13:29:14.773 に答える
-1

このキャストで試してください:

void ApplicationApi(void * DataPtr)
{
  *(float32*)DataPtr = *(float32*)unsignedLong_val;
}

正しい値が float 値であることを宣言する必要があります。
あなたのキャストでは、右の値は整数で、左の値は float です。コンパイラは、整数を float 値に暗黙的に変換します。

于 2013-08-22T06:46:28.873 に答える