ハードウェア分割のないCortex M0 cpuで作業しているので、何かを分割するたびにGCCライブラリ関数が使用されます。現在、私が最もよく行う除算の 1 つは、256 で除算して、short をバイトに変換することです。デフォルトの GCC ライブラリよりも効率的に (ビットシフトなどで) これを行う方法はありますか?
2705 次
3 に答える
7
あなたのコメントによると、-32768 を 0 にマップし、32767 を 255 にマップする必要があります。したがって、必要な式は次のとおりです。
short s = /* input value */;
unsigned char c = (unsigned char) ((s + 32768) / 256);
他のコメント投稿者は、右シフトまたはその他のさまざまな戦術を使用して 256 で割ることができると述べていますが、これは本当です。これの合理的なバージョンは次のようになります。
unsigned char c = (unsigned char) ((s + 32768) >> 8);
ただし、そのような最適化は必要ありません。GCC は、定数による除算演算を特別なケースの実装に変換することについて非常にスマートです。この場合、これらの両方をまったく同じコードにコンパイルします (-O2 -mcpu=cortex-m0 -mthumb
および GCC 4.7.2 でテスト済み)。
mov r3, #128
lsl r3, r3, #8
add r0, r0, r3
lsr r0, r0, #8
uxtb r0, r0
あまりにも賢くしようとすると(他の回答のユニオンまたはポインターキャストの例のように)、混乱してさらに悪い結果になる可能性があります-特にそれらはメモリロードによって機能し、32768を追加すると、すでに持っていることを意味しますレジスタ内の値。
于 2013-02-03T19:06:53.953 に答える
2
ポインタをキャストするだけです。
unsigned char *bytes = (unsigned char*)&yourvalue;
今、bytes[0]
あなたの値の1バイトを保持し、bytes[1]
他のバイトを保持します。順序はシステムのエンディアンに依存します
于 2013-02-03T16:57:37.597 に答える
1
次のように使用できますunion
。
#include <stdio.h>
union Word {
struct {
unsigned char high;
unsigned char low;
} byte;
unsigned short word;
};
int main(int argc, char **argv) {
union Word word;
word.word = 0x1122;
printf("L = 0x%x, H = 0x%x", word.byte.low, word.byte.high);
return 0;
}
于 2013-02-03T17:09:04.277 に答える