2

IEEE単精度浮動小数点数を特定のアドレスの32ビットハードウェアレジスタに書き込む必要があります。そのためには、float型の変数を符号なし整数に変換する必要があります。私はこのような整数表現を得ることができます:

float a = 2.39;
unsigned int *target;
printf("a = %f\n",a);
target = &a;
printf("target = %08X\n",*target);

これは次を返します:

a = 2.390000
target = 4018F5C3

すべて良い。ただし、これにより、コンパイラの警告「cast.c:12:警告:互換性のないポインタ型からの割り当て」が発生します。

警告を生成しないこれを行う他の方法はありますか?これは特定のハードウェア用であり、異なるエンディアンなどを処理する必要はありません。また、他のいくつかの質問が示唆する傾向があるため、パフォーマンス上の理由から各文字をループしたくありません。C ++でreinterpret_castを使用できるようですが、私はCを使用しています。

4

4 に答える 4

5

ユニオンで型のパンニングを使用できます、

union {
    float f;
    uint32_t u;
} un;
un.f = your_float;
uint32_t target = un.u;

ビットを取得します。または、を使用できますmemcpy

于 2012-07-24T19:47:57.103 に答える
1

次のように、floatとunsigned intを含む型を作成しunion、値をfloatメンバーに格納してから、intから読み取ることができます。

union reg_val
{
  float f_val;
  unsigned int i_val;
} myRegister;
myRegister.f_val = 2.39;
printf("target = %08X", myRegister.i_val);
于 2012-07-24T19:49:44.457 に答える
0

メモリに保存されているのの整数値を単純に表示しようとしている場合は、ユニオンを使用してみてください。float

union {
    float a;
    unsigned int target;
} u;

float値を保存します。

u.a = 2.39;

float値と整数値の両方を出力します。

printf ("a = %f\n", u.a);
printf ("target = %08X\n", u.target); /* you could use %u to show decimal */

コンパイラの警告はありません。LinuxではGNUコンパイラ(gcc)を使用しています。これはポインタでtargetないことに注意してください。これが組合の美しさ(そして恐ろしさ)です。;-)

于 2012-07-24T20:02:50.200 に答える
0

編集:ユニオンソリューションは、私が試したすべての場所で機能しますが、SOのどこかで、機能する必要がないことを示す標準が指摘されていました。コメントの以下のリンクを参照して、これに関する多くの詳細情報を見つけてください(ダニエルに感謝します!)。動作する場合と動作しない場合は注意して使用しますが、エンディアンなども関係していると思います(ダブルがバイトに分割されるなど)。

別の解決策は、ダミーのasm関数です。たとえば、腕の場合:

.globl echo 
echo:
   bx lr


unsigned int echo ( float );
...
unsigned int ra; float f;
f=1.0;
ra=echo(f);

ある程度の分解が必要であり、fpuを持たないシステム上にある必要があり、および/またはフロートを持ち運ぶためにgprsを使用する必要があります。

すでに述べたように、memcpyは、最もクリーンで信頼性が高く、ポータブルなソリューションです(エンディアンに注意してください)。

于 2012-07-24T20:34:00.107 に答える