wake-up-neo.net

C/C++ - Prüfung, ob ein Bit gesetzt ist, d. H. Int-Variable

int temp = 0x5E; // in binary 0b1011110.

Gibt es eine Möglichkeit, zu prüfen, ob das Bit 3 in Temp 1 oder 0 ist, ohne dass Bit verschoben und maskiert wird.

Ich möchte nur wissen, ob es dafür eine eingebaute Funktion gibt, oder bin ich gezwungen, selbst eine zu schreiben.

88
Milan

Wenn Sie in C die Bitmanipulation ausblenden möchten, können Sie ein Makro schreiben:

#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))

und benutze es so:

CHECK_BIT(temp, 3)

In C++ können Sie std :: bitset verwenden.

139
mouviciel

Prüfen Sie, ob das Bit N (ab 0) gesetzt ist:

temp & (1 << N)

Dafür gibt es keine eingebaute Funktion.

72
Joao da Silva

Ich würde nur ein std :: bitset verwenden, wenn es C++ ist. Einfach. Einfach. Keine Chance für dumme Fehler.

typedef std::bitset<sizeof(int)> IntBits;
bool is_set = IntBits(value).test(position);

oder wie wäre es mit dieser Dummheit

template<unsigned int Exp>
struct pow_2 {
    static const unsigned int value = 2 * pow_2<Exp-1>::value;
};

template<>
struct pow_2<0> {
    static const unsigned int value = 1;
};

template<unsigned int Pos>
bool is_bit_set(unsigned int value)
{
    return (value & pow_2<Pos>::value) != 0;
} 

bool result = is_bit_set<2>(value);
21
user21714

Gemäß dieser Beschreibung von Bitfeldern gibt es eine Methode, Felder direkt zu definieren und darauf zuzugreifen. Das Beispiel in diesem Eintrag lautet:

struct preferences {
    unsigned int likes_ice_cream : 1;
    unsigned int plays_golf : 1;
    unsigned int watches_tv : 1;
    unsigned int reads_books : 1;
}; 

struct preferences fred;

fred.likes_ice_cream = 1;
fred.plays_golf = 1;
fred.watches_tv = 1;
fred.reads_books = 0;

if (fred.likes_ice_cream == 1)
    /* ... */

Dort gibt es auch eine Warnung:

Bit-Member in structs haben jedoch praktische Nachteile. Erstens hängt die Reihenfolge der Bits im Speicher von der Architektur ab, und die Regeln für die Auffüllung des Speichers variieren von Compiler zu Compiler. Darüber hinaus generieren viele gängige Compiler ineffizienten Code zum Lesen und Schreiben von Bitelementen, und es gibt potenziell schwerwiegende Thread-Sicherheitsprobleme in Bezug auf Bitfelder (insbesondere auf Multiprozessorsystemen), da die meisten Maschinen keine beliebigen Bitsätze im Speicher bearbeiten können. sondern muss stattdessen ganze Wörter laden und speichern.

11
gimel

Ja, ich weiß, dass ich"nicht habe", um es so zu machen. Normalerweise schreibe ich:

    /* Return type (8/16/32/64 int size) is specified by argument size. */
template<class TYPE> inline TYPE BIT(const TYPE & x)
{ return TYPE(1) << x; }

template<class TYPE> inline bool IsBitSet(const TYPE & x, const TYPE & y)
{ return 0 != (x & y); }

Z.B.:

IsBitSet( foo, BIT(3) | BIT(6) );  // Checks if Bit 3 OR 6 is set.

Dieser Ansatz ist unter anderem:

  • Für 8/16/32/64-Bit-Ganzzahlen.
  • Erkennt IsBitSet (int32, int64) -Aufrufe ohne mein Wissen und meine Zustimmung.
  • Inline Template, also keine Funktion, die Overhead aufruft.
  • const & referenzen, so dass nichtsdupliziert/kopiert werden muss. Und wir sind garantiert, dass der Compiler alle Typos aufnimmt, die versuchen, die Argumente zu ändern.
  • 0! = macht den Code klarer und offensichtlicher. Beim Schreiben von Code geht es in erster Linie darum, klar und effizient mit anderen Programmierern zu kommunizieren, auch mit geringerem Geschick.
  • Dies gilt zwar nicht für diesen speziellen Fall ... Im Allgemeinen vermeiden Templated-Funktionen das Problem, Argumente mehrmals auszuwerten. Ein bekanntes Problem mit einigen #define-Makros. 
    Zum Beispiel: # Definieren von ABS (X) (((X) <0) & alpha; - (X): (X)) 
    ABS (i ++);
10
Mr.Ree

Was die ausgewählte Antwort tatsächlich tut, ist falsch. Die unten stehende Funktion gibt die Bitposition oder 0 zurück, je nachdem, ob das Bit tatsächlich aktiviert ist. Das wollte das Poster nicht.

#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))

Hier war das, wonach das Poster ursprünglich gesucht hatte. Die unten stehende Funktion gibt entweder 1 oder 0 zurück, wenn das Bit aktiviert ist, und nicht die Position.

#define CHECK_BIT(var,pos) (((var)>>(pos)) & 1)
8
shocker92

Sie können ein Bitset - http://www.cppreference.com/wiki/stl/bitset/start verwenden.

5
yawmark

Verwenden Sie std :: bitset

#include <bitset>
#include <iostream>

int main()
{
    int temp = 0x5E;
    std::bitset<sizeof(int)*CHAR_BITS>   bits(temp);

    // 0 -> bit 1
    // 2 -> bit 3
    std::cout << bits[2] << std::endl;
}
4
Martin York

Es gibt nämlich die _bittest intrinsische Anweisung.

4

ich habe versucht, eine 32-Bit-Ganzzahl zu lesen, die die Flags für ein Objekt in PDF-Dateien definiert, und dies hat für mich nicht funktioniert

was wurde behoben?

#define CHECK_BIT(var,pos) ((var & (1 << pos)) == (1 << pos))

der Operand & gibt eine Ganzzahl mit den Flags zurück, die beide in 1 haben, und es wurde nicht richtig in Boolean umgewandelt

3
Ismael

Ich benutze das:

#define CHECK_BIT(var,pos) ( (((var) & (pos)) > 0 ) ? (1) : (0) )

wobei "pos" als 2 ^ n definiert ist (zB 1,2,4,8,16,32 ...)

Kehrt zurück: 1 wenn wahr 0 wenn falsch

2
AnthropicDream

Sie können das Verschieben und Maskieren "simulieren": if ((0x5e/(2 * 2 * 2))% 2) ...

2
Leonidas

Verwenden Sie für die x86-spezifische Low-Level-Lösung den x86 TEST opcode.

Dein Compiler sollte _bittest in diese Situation einbinden ...

2
jheriko

Warum nicht etwas so einfaches verwenden?

uint8_t status = 255;
cout << "binary: ";

for (int i=((sizeof(status)*8)-1); i>-1; i--)
{
  if ((status & (1 << i)))
  {
    cout << "1";
  } 
  else
  {
    cout << "0";
  }
}

OUTPUT: binär: 11111111

1
zeilja

wenn Sie nur einen wirklich hart codierten Weg wollen:

 #define IS_BIT3_SET(var) ( ((var) & 0x04) == 0x04 )

beachten Sie diese hw-abhängig und nimmt diese Bitreihenfolge 7654 3210 an und var ist 8 Bit.

#include "stdafx.h"
#define IS_BIT3_SET(var) ( ((var) & 0x04) == 0x04 )
int _tmain(int argc, _TCHAR* argv[])
{
    int temp =0x5E;
    printf(" %d \n", IS_BIT3_SET(temp));
    temp = 0x00;
    printf(" %d \n", IS_BIT3_SET(temp));
    temp = 0x04;
    printf(" %d \n", IS_BIT3_SET(temp));
    temp = 0xfb;
    printf(" %d \n", IS_BIT3_SET(temp));
    scanf("waitng %d",&temp);

    return 0;
}

Ergebnisse in:

1 0 1 0

0
simon

Ein Ansatz wird unter folgenden Bedingungen überprüft:

if ( (mask >> bit ) & 1)

Ein Erklärungsprogramm wird sein:

#include <stdio.h>

unsigned int bitCheck(unsigned int mask, int pin);

int main(void){
   unsigned int mask = 6;  // 6 = 0110
   int pin0 = 0;
   int pin1 = 1;
   int pin2 = 2;
   int pin3 = 3;
   unsigned int bit0= bitCheck( mask, pin0);
   unsigned int bit1= bitCheck( mask, pin1);
   unsigned int bit2= bitCheck( mask, pin2);
   unsigned int bit3= bitCheck( mask, pin3);

   printf("Mask = %d ==>>  0110\n", mask);

   if ( bit0 == 1 ){
      printf("Pin %d is Set\n", pin0);
   }else{
      printf("Pin %d is not Set\n", pin0);
   }

    if ( bit1 == 1 ){
      printf("Pin %d is Set\n", pin1);
   }else{
      printf("Pin %d is not Set\n", pin1);
   }

   if ( bit2 == 1 ){
      printf("Pin %d is Set\n", pin2);
   }else{
      printf("Pin %d is not Set\n", pin2);
   }

   if ( bit3 == 1 ){
      printf("Pin %d is Set\n", pin3);
   }else{
      printf("Pin %d is not Set\n", pin3);
   }
}

unsigned int bitCheck(unsigned int mask, int bit){
   if ( (mask >> bit ) & 1){
      return 1;
   }else{
      return 0;
   }
}

Ausgabe:

Mask = 6 ==>>  0110
Pin 0 is not Set
Pin 1 is Set
Pin 2 is Set
Pin 3 is not Set
0
Michi

Es ist zwar ziemlich spät, jetzt zu antworten, aber es gibt eine einfache Möglichkeit, herauszufinden, ob das N-te Bit gesetzt ist oder nicht, und zwar mit mathematischen Operatoren POWER und MODULUS.

Nehmen wir an, wir möchten wissen, ob bei 'Temp' das N-te Bit gesetzt ist oder nicht. Der folgende boolesche Ausdruck gibt true zurück, wenn das Bit gesetzt ist, andernfalls 0.

  • (Temp MODULUS 2 ^ N + 1> = 2 ^ N)

Betrachten Sie das folgende Beispiel:

  • int temp = 0x5E; // in binär 0b1011110 // BIT 0 ist LSB

Wenn ich wissen will, ob das 3. Bit gesetzt ist oder nicht, bekomme ich

  • (94 MODULUS 16) = 14> 2 ^ 3

Der Ausdruck gibt also true zurück, um anzuzeigen, dass das 3. Bit gesetzt ist.

0
Ouroboros