負の数、0、または正の数を返す関数がある場合。代わりに、正の数の場合は-1を返し、0の場合は0を返し、正の数の場合は+1を返します。これは、ある種のビットマジックを使用して達成することは可能ですか?
何らかのビットバイディングを使用してこのようなことを達成できますか、通常の比較を行う必要がありますか?
負の数、0、または正の数を返す関数がある場合。代わりに、正の数の場合は-1を返し、0の場合は0を返し、正の数の場合は+1を返します。これは、ある種のビットマジックを使用して達成することは可能ですか?
何らかのビットバイディングを使用してこのようなことを達成できますか、通常の比較を行う必要がありますか?
符号ビットのテストを使用することはできますが、整数サイズについての仮定を持たせる以外にも、ゼロをテストする必要があります。ほとんどのコンパイラで非常に高速な確かに
if (myvalue > 0)
return 1;
else if (myvalue < 0)
return -1;
else
return 0;
クリーン、明示的な、ポータブルおよび:
は、代わりに私は、次の「魔法」を示唆しています。私が示唆している唯一のもっともらしいコードレベルの最適化は、このケースがより頻繁であることを知っていれば、最初に0(ゼロ)の値をテストすることです。
非常に良い。シンプルは複合化よりも優れています。 – user1277476
私は、(a)あなたが負の数に対して-1を意味し、(b)その範囲が-254から+254であったと仮定しよう。
ネガティブかポジティブかは1ビットのみで調べることができますが、ゼロをテストするにはすべてのビットを検査してすべてゼロであることを確認する必要があります。ビット操作 "ショートカット"。
ビットで遊ぶことでこれを達成することは間違いありませんが、それを行う方法を想像できない場合は、後でコードを操作する人々がそれを読むことができるとは期待できません。
if-elseステートメントを使用するだけで、コードはより簡単になり、より重要なプログラミング(またはSO :)で移動することができます)。
整数が2の補数を使用して表される場合、最上位ビットのみを見るだけでよい。 1の場合は負、そうでない場合は正または0です。
も参照してください:
2's Complementはちょうどその大きさによって数を分割し、あなたが看板を得るでしょう、奇妙なビットの魔法のために見てはいけません。
私が正しく質問を理解した場合:
static inline int sign(unsigned int n){
int sign_bit = n >> (sizeof(int)*CHAR_BIT - 1); //sign_bit = n<0 will also do
int is_zero = !n;
return 1 - is_zero - sign_bit * 2;
};
をそれはロジックを示すために、「圧縮」ではありません。
2の補数を仮定したい場合は、符号付きの型の右シフトは算術演算です(これらの仮定は移植性はありませんが、多くの一般的なプラットフォームでは成立しません)。半分にすぎ巧妙なもの:
int number;
const int shift = sizeof number * CHAR_BIT - 1;
return (number >> shift) - (-number >> shift);
かなり不可解な何かのためのバンチ仮定し、それが任意のプラットフォーム上で、実際に高速だと保証なし。
あなたはきちんと表現を探しているなら:あなたは魔法をやりたいのはなぜ
return (val > 0) - (val < 0);
...読むのに数秒以上かかる! –
?マジックはあまり分かりません。また、数字が0から254の範囲であれば、-1という数字と正の数字は1がついているので、「負の数の場合は-1」を意味すると仮定します。負? –
私はあなたの質問を理解できません! – AraK
引数のデータ型は何ですか? – tmiddlet