web-dev-qa-db-ja.com

C / C ++の最下位ビット(LSB)および最上位ビット(MSB)の値を確認します

C/C++の整数の最下位ビット(LSB)と最上位ビット(MSB)の値を確認する必要があります。どうすればいいですか?

21
delaccount992
//int value;
int LSB = value & 1;

別の方法として(理論的には移植性はありませんが、実際には移植可能です-Steveのコメントを参照してください)

//int value;
int LSB = value % 2;

詳細:2番目の式はより単純です。 %演算子は剰余演算子です。数値のLSBは、奇数の場合は1、それ以外の場合は0です。したがって、除算の残りを2でチェックします。最初の式のロジックは次のとおりです。バイナリの1は次のとおりです。

0000...0001

これを任意の数とバイナリANDすると、結果のすべてのビットは0になります。ただし、0 ANDその他は0であるため、結果の最後のビットは1になります。なぜなら1 & 1 == 1および1 & 0 == 0

This はビット単位の操作に適したチュートリアルです。

HTH。

21
Armen Tsirunyan

次のようなことができます:

#include <iostream>

int main(int argc, char **argv)
{
    int a = 3;
    std::cout << (a & 1) << std::endl;
    return 0;
}

このようにして、LSBで変数をANDします。

3: 011
1: 001

3ビット表現。したがって、AND

AND
-----
0  0  | 0
0  1  | 0
1  0  | 0
1  1  | 1

LSBが1かどうかを知ることができます。

edit:MSBを見つけます。

最初に Endianess の記事を読んで、MSBの意味に同意してください。次の行では、ビッグエンディアン表記で処理することを想定しています。

MSBを見つけるために、次のスニペットでは、MSB1ANDedになるまで右シフトを適用することに焦点を当てます。次のコードを検討してください。

#include <iostream>
#include <limits.h>

int main(int argc, char **argv)
{
    unsigned int a = 128; // we want to find MSB of this 32-bit unsigned int
    int MSB = 0;   // this variable will represent the MSB we're looking for

    // sizeof(unsigned int) = 4 (in Bytes)
    // 1 Byte = 8 bits
    // So 4 Bytes are 4 * 8 = 32 bits
    // We have to perform a right shift 32 times to have the
    // MSB in the LSB position.
    for (int i = sizeof(unsigned int) * 8; i > 0; i--) {

        MSB = (a & 1); // in the last iteration this contains the MSB value

        a >>= 1; // perform the 1-bit right shift
    }

    // this prints out '0', because the 32-bit representation of
    // unsigned int 128 is:
    // 00000000000000000000000010000000
    std::cout << "MSB: " << MSB << std::endl; 

    return 0;
}

サイクル外でMSBを出力すると、0が返されます。 aの値を変更する場合:

unsigned int a = UINT_MAX; // found in <limits.h>

MSB1になります。これは、32ビット表現が次のとおりであるためです。

UINT_MAX: 11111111111111111111111111111111

ただし、signed integerを使用して同じことを行うと、状況は異なります。

#include <iostream>
#include <limits.h>

int main(int argc, char **argv)
{
    int a = -128; // we want to find MSB of this 32-bit unsigned int
    int MSB = 0; // this variable will represent the MSB we're looking for

    // sizeof(int) = 4 (in Bytes)
    // 1 Byte = 8 bits
    // So 4 Bytes are 4 * 8 = 32 bits
    // We have to perform a right shift 32 times to have the
    // MSB in the LSB position.
    for (int i = sizeof(int) * 8; i > 0; i--) {

        MSB = (a & 1); // in the last iteration this contains the MSB value

        a >>= 1; // perform the 1-bit right shift
    }

    // this prints out '1', because the 32-bit representation of
    // int -128 is:
    // 10000000000000000000000010000000
    std::cout << "MSB: " << MSB << std::endl; 

    return 0;
}

以下のコメントで述べたように、正の整数MSBは常に0であり、一方負の整数MSBは常に1です。

INT_MAX 32ビット表現を確認できます。

INT_MAX: 01111111111111111111111111111111

今。サイクルがsizeof()を使用する理由コメントで書いたように単純にサイクルを実行する場合:(コメントに=がありませんでした)

for (; a != 0; a >>= 1)
    MSB = a & 1;

c ++は、最高の1よりも高い「ゼロパッドビット」(終了ステートメントとしてa != 0を指定したため)を考慮しないため、常に1を取得します。たとえば、32ビット整数の場合:

int 7 : 00000000000000000000000000000111
                                     ^ this will be your fake MSB
                                       without considering the full size 
                                       of the variable.

int 16: 00000000000000000000000000010000
                                   ^ fake MSB
13
dave
int LSB = value & 1;
int MSB = value >> (sizeof(value)*8 - 1) & 1;
6
Zdeněk Pavlas

他の人はすでに言及しています:

int LSB = value & 1;

最下位ビットを取得します。ただし、MSBを取得するには、これまでに説明した方法よりも簡単な方法があります。値が既に符号付き型である場合は、次を実行します。

int MSB = value < 0;

符号なしの数量の場合、同じサイズの符号付きタイプにキャストします。 valueunsignedとして宣言されている場合、次のようにします。

int MSB = (int)value < 0;

はい、公式には、移植性がなく、未定義の動作は何でも。しかし、私が知っている2の補数システムとそれらのすべてのコンパイラーでは、たまたま動作します。結局、上位ビットは符号ビットであるため、符号付き形式が負の場合、MSBは1になり、負でない場合、MSBは0になります。したがって、負の数の符号付きテストは、 MSB。

2
ShadowRanger

LSBは簡単です。 xと1だけ。

バイトは8ビットではなく、sizeof(int)は4ではなく、右側にパディングビットがあるため、MSSBは少し複雑です。

また、符号付き整数とは、MS値ビットの符号ビットを意味しますか?.

あなたがサインビットを意味するなら、人生は簡単です。 x <0です

最上位ビットを意味する場合、完全に移植可能です。

 int answer  = 0;
 int rack = 1;
 int mask  = 1;

 while(rack < INT_MAX)
 {
    rack << = 1;
    mask << = 1;
    rack |= 1; 
 } 

 return x & mask;

それは長い時間をかけて行われた方法です。現実には

x&(1 <<(sizeof(int)* CHAR_BIT)-2);非常に移植性が高く、intにはパディングビットがありません。

0
Malcolm McLean