署名された符号なしで解釈します
-
28-10-2019 - |
質問
私は組み込みプラットフォーム(ARM)に取り組んでおり、ビットパターンを扱うときは注意する必要があります。この行は私の影響を超えているふりをしましょう:
uint8_t foo = 0xCE; // 0b11001110
署名なしと解釈されるこれは206です。しかし、実際には署名されているため、似ています -50. 。署名どおりにこの値を使用し続けるにはどうすればよいですか?
int8_t bar = foo; // doesn't work
どちらもしません(すべての入力値に対して0x10または0x00になります)
int8_t bar = static_cast<int8_t>(foo);
int8_t bar = reinterpret_cast<int8_t&>(foo);
ビットを触れられないようにしたいだけです。 (bar == 0xCE)
その逆も、マイナス数を表すビットパターを、ビットパターンを台無しにすることなく署名していない変数にする方法に興味があります。 GCCを使用しています。
解決
以下は私のために正常に機能します、 本来あるべきです コメントが言うように、これは実装定義です:
int x = (signed char)(foo);
C ++では、次のように言うこともできます。
int x = static_cast<signed char>(foo);
プロモーションは常に保存しようとすることに注意してください 価値 ビットパターンを再解釈する前に。したがって、最初に、署名されたタイプと同じサイズの署名型タイプにキャストして、署名された再解釈を強制する必要があります。
(印刷しようとするとき、私は通常反対の問題に直面しています char
s160桁のペアとして。)
他のヒント
uint8_t foo = 0xCE; // 0b11001110
int8_t bar;
memcpy( &bar, &foo, 1 );
コンパイラの99%がMemcpyへの呼び出しを完全に最適化するという追加のボーナスもあります...
この線に沿って醜い何か?
int8_t bar = (foo > 127) ? ((int)foo - 256) : foo;
動作が未定義の変換に依存していません。
GCCの可能性は、埋め込まれたプラットフォームであっても、署名されていない値が2つの補完であるということです。
次に、8ビット番号 0xCE
表現します 0xCE-256
.
2つの補完は実際には単なるModulo 2だけだからですn, 、 どこ n 表現のビット数です。
編集: :hm、担当者のために、具体的な例を挙げた方が良いでしょう。
int8_t toInt8( uint8_t x )
{
return (x >= 128? x - 256 : x);
}
編集2: :署名されていない変数に少しパターンを取得する方法についての最後の質問は見られませんでした。それは非常に簡単です:ただ割り当ててください。結果は、C ++標準によって保証されています。つまり、保存された値は、割り当てられた値と一致している(24時間面等しい)ことです。n.
乾杯&hth。、
ポインターを使用して値の表現にアクセスできます。値タイプではなくポインタータイプを再解釈することにより、表現を複製できるはずです。
uint8_t foo = 0xCE;
int8_t bar = *reinterpret_cast<int8_t*>(&foo);