オンラインバイトからfloatを再構築
-
19-09-2019 - |
質問
私は、マイクロプロセッサのPIC32MXシリーズにハイテックPICC32で働いているが、私はのsizeofで、これはC90とほぼ同等である(この質問はC.で知力誰のために十分一般的だと思います(INT)=はsizeof(長いです)= sizeof(フロート)= 4である。)
のは、私がfloat
を表すデータの4バイトワードを読みましょう。私はすぐにその実際の浮動小数点値に変換することができます:
#define FLOAT_FROM_WORD(WORD_VALUE) (*((float*) &(WORD_VALUE)))
しかし、これは左辺値で動作します。私は、例えば、関数の戻り値でこれを使用することはできませんように。
FLOAT_FROM_WORD(eeprom_read_word(addr));
関数呼び出しまたは一時変数なしで、このインライン、すなわちを行うには、短いと甘い方法はありますか?正直に言うと、そこに私は、関数呼び出しや余分なVARを避けるための巨大な理由はないのですが、それは私を盗聴です。私が欠けている方法があるに違いありません。
を追加しました:の私はそれWORD
が実際に共通のtypedefだった実現しませんでした。私は混乱を避けるために、マクロ引数の名前を変更しました。
解決
あなたはトリックに戻り値のための他の方法を実行することができます。
float fl;
*(int*)&fl = eeprom_read_word(addr);
または
#define WORD_TO_FLOAT(f) (*(int*)&(f))
WORD_TO_FLOAT(fl) = eeprom_read_word(addr);
またはRサミュエルKlatchkoが示唆するように
#define ASTYPE(type, val) (*(type*)&(val))
ASTYPE(WORD,fl) = eeprom_read_word(addr);
他のヒント
これはGCCがあった場合は、あなたがこれを行うことができます:
#define atob(original, newtype) \
(((union { typeof(original) i; newtype j })(original)).k)
うわー。恐ろしいです。しかし、使い方がいいです。
int i = 0xdeadbeef;
float f = atob(i, float);
私は標準的な動作ではないが、あなたのコンパイラがtypeof
鋳造を行うことができますオフのチャンスでは、それはあなたの答えもされていないので、あなたのコンパイラは、union
演算子やGCCがないこと、鋳造union
のいずれかをサポートしていません賭けます。 typeof
を使用しないように変更されます:
#define atob(original, origtype newtype) \
(((union { origtype i; newtype j })(original)).k)
int i = 0xdeadbeef;
float f = atob(i, int, float);
もちろん、これはあなたが、異なるサイズの2種類を使用するときに何が起こるかの問題を無視し、代わりに追加のパラメータを取るのは、値を返します。つまり、単純なマクロフィルター「あなたが望むもの」に近いです。このバージョンでは、かかる追加のパラメータは単なる一般のためのものです。
あなたのコンパイラがきちんとあるが、非ポータブルトリックですunion
キャストをサポートしていない場合は、は、その後、「あなたがそれを望むように」これを行う方法はありませんし、他の答えはすでにそれを持っています。
あなたはconst参照を使用する場合は、一時的な値のアドレスを取ることができます:
FLOAT_FROM_WORD(w) (*(float*)&(const WORD &)(w))
が、それがCに動作しません:(
(cは参照が権利がないのですか?ビジュアルC ++で作品を)
他の人がそれをインライン関数、または定義にTEMPである、と述べているように、、コンパイラはそれを最適化します。
そうでもない答えは、より多くの提案。それは持っていない場合、あなたのFLOAT_FROM_WORDマクロを使用するのがより自然でより柔軟になります。最後に
#define FLOAT_FROM_WORD(w) (*(float*)&(w))
fl = FLOAT_FROM_WORD(wd);
これは、あなたの正確な状況で可能で、あまりにもあなたの問題を解決するだろうC99コンパイラにアップグレードしない場合があります。
C99マクロの欠点なしでまさにこの場合に改善された効率を得るため、パラメータの正常な機能のように作用しながら、インライン関数を持ち、値を返す。