web-dev-qa-db-ja.com

Cでビット演算子のみを使用して、数値xが正(x> 0)であるかどうかを確認します

isPositive-_x > 0_の場合はtrueを返し、それ以外の場合はfalseを返します

例:isPositive(-1)

法務:_!_ _~_ _&_ _^_ _|_ _+_ _<<_ _>>_

最大操作数:_8_

注:条件文は使用できません。

_inline bool isPositive(int32_t x) {
  return ???;
}
_
16
Eternal Learner
return !((x & 0x80000000) >> 31 | !x);
11
Matthew
int isPositive(int x) {
   return !((x&(1<<31)) | !x);
}

x&(1<<31は、数値が負であるかどうかを確認することです。

!xは、数値がゼロかどうかを確認することです。

数値が負でもゼロでもない場合、その数値は正です。

19
codaddict
int isPositive(int x)
{
 return (!(x & 0x80000000) & !!x); 
}
10
Henrik

符号ビットで遊んでみましょう:sign(~n):1 if n> = 0

nが0の場合を取り除くには:sign(~n + 1):1(n> 0またはn = MIN_INTの場合)

したがって、両方の関数が1を返す場合が必要です。

return ((~n & (~n + 1)) >> 31) & 1;
3
ruslik

XOR (^)を使用してみませんか?

これを試して、

{
    return ((x>>31)&1)^(!!x); 
}

0ケースにもうまく対応できます。

3
Kira Gao

2の補数表現を想定すると(常にそうであるとは限りません!)、これは最上位ビットが設定されているかどうかをテストすることで実現できます(この場合、数値は負です)。

次のコードは不正な操作を使用していることに注意してください(+*および-)ただし、これらは明確さとプラットフォームの独立性のみを目的としています。特定のプラットフォームについて詳しく知っている場合、たとえばintは32ビットの数値であるため、関連する定数を数値に置き換えることができます。

// Will be 1 iff x < 0.
int is_neg = (x & (INT_MAX + 1)) >> (CHAR_BIT * sizeof(int) - 1);
// Will be 1 iff x != 0.
int is_not_zero = !!x;
return !is_neg & is_not_zero;
1
Konrad Rudolph

ここに別のオプションがあります:

int is_positive = (0&x^((0^x)&-(0<x)));

それはただの(0&min(0、x))です。

テスト ここ

0
user9869932

サイネージビットとしてMSBを使用する記数法を使用している場合は、次のことができます。

int IsPositive(int x)
{
    return (((x >> 31) & 1) ^ 1) ^ !x;
}
0
Necrolis

かなり長い間アセンブラを実行していませんが、私が覚えている限り、Wordの最初の桁は負の値を表します。 1000は-8であるため、最上位ビットが1の場合、数値は負になります。したがって、答えは!(x>>31)です。

0
Vitalij