views:

9448

answers:

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

Is there such a way to check if bit 3 in temp is 1 or 0 without bit shifting and masking.

Just want to know if there is some built in function for this, or am I forced to write one myself.

+5  A: 

You can use a Bitset - http://www.cppreference.com/wiki/stl/bitset/start.

yawmark
+8  A: 

Check if bit N (starting from 0) is set:

temp & (1 << N)

There is no builtin function for this.

João da Silva
+1 for mentioning it's starting from 0 since I suspect the OP was thinking 1-based and the accepted answer will get him into trouble. :)
Jim Buck
+16  A: 

In C, if you want to hide bit manipulation, you can write a macro:

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

and use it this way:

CHECK_BIT(temp, 3)

In C++, you can use std::bitset.

mouviciel
Eduard - Gabriel Munteanu
@Eduard: in C, everything `!= 0` is true, so why bother? `1` is exactly as true as `0.1415`!
Christoph
And in case you're using C++, you could (should) write a template instead of a macro. :)
jalf
In C this is fine. But this kind of macros in C++. That's horrible and so open to abuse. Use std::bitset
Martin York
Use std::bitset indeed.
Dave Van den Eynde
This is a common C solution; but as mentioned, in C++ std::bitset will get you all of the speed and clarity with far, far fewer hassles of preprocessor macros.
Shmoopty
Thanks, I've updated my answer by adding std::bitset.
mouviciel
A: 

You could "simulate" shifting and masking: if((0x5e/(2*2*2))%2) ...

Leonidas
We could sort a list by randomly shuffling it and testing to see if it's now "sorted". E.g.: while( /*NOT*/! isSorted() ) { RandomlyShuffle(); } But we don't...
Mr.Ree
This solution is extremely wasteful on resources and unintuitive. divs, muls and mods are the three most expensive functions. by comparision tests, ands and shifts are among the cheapest - some of the few you might actually get done in less than 5 cycles.
jheriko
That might be (and is not, because modern processors detest bits and jumps). The OP originally asked _explicitly_ for a solution "without bit shifting and masking." So go on and give more negative points for a matching but slow answer. I won't delete the post just because the OP changed his mind.
Leonidas
+5  A: 

There is, namely the _bittest intrinsic instruction.

Dave Van den Eynde
The link indicates "Microsoft Specific". Use it only if you don't need your code to be portable.
mouviciel
I learned something new today - thank you!
SAMills
The link indicates "Microsoft Specific", but it's an intrinsic taken over from the Intel C++ compiler, and it results in a BT instruction, so you can do it with inline assembler too. Of course, that doesn't make it more portable.
Dave Van den Eynde
It's also specific to the x86 architecture. So no, definitely not portable.
jalf
I'm sure other architectures have similar options.
Dave Van den Eynde
The very point of intrinsics is that they take advantage of hardware if it exists, and use a software replacement if the hardware does not handle it.
Eclipse
Yes, but it's a function that is not in the standard, so it's not really portable. But it's a trivial thing to support in platforms that don't support it by themselves.
Dave Van den Eynde
+5  A: 

According to this description of bit-fields, there is a method for defining and accessing fields directly. The example in this entry goes:

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)
    /* ... */

Also, there is a warning there:

However, bit members in structs have practical drawbacks. First, the ordering of bits in memory is architecture dependent and memory padding rules varies from compiler to compiler. In addition, many popular compilers generate inefficient code for reading and writing bit members, and there are potentially severe thread safety issues relating to bit fields (especially on multiprocessor systems) due to the fact that most machines cannot manipulate arbitrary sets of bits in memory, but must instead load and store whole words.

gimel
A: 

if you just want a real hard coded way:

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

note this hw dependent and assumes this bit order 7654 3210 and var is 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;
}

Results in:

1 0 1 0

simon
Remo.D
Hi Remo.D -- Not sure I understand your comment? I have include some 'c' code that works just fine.
simon
His point is that it's not hardware-dependant - IS_BIT3_SET will always test the 4th least significant bit
Eclipse
+4  A: 

Yeah, I know I don't "have" to do it this way. But I usually write:

    /* 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); }

E.g.:

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

Amongst other things, this approach:

  • Accommodates 8/16/32/64 bit integers.
  • Detects IsBitSet(int32,int64) calls without my knowledge & consent.
  • Inlined Template, so no function calling overhead.
  • const& references, so nothing needs to be duplicated/copied. And we are guaranteed that the compiler will pick up any typo's that attempt to change the arguments.
  • 0!= makes the code more clear & obvious. The primary point to writing code is always to communicate clearly and efficiently with other programmers, including those of lesser skill.
  • While not applicable to this particular case... In general, templated functions avoid the issue of evaluating arguments multiple times. A known problem with some #define macros.
    E.g.: #define ABS(X) (((X)<0) ? - (X) : (X))
          ABS(i++);
Mr.Ree
+5  A: 

I would just use a std::bitset if it's C++. Simple. Straight-forward. No chance for stupid errors.

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

or how about this silliness

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);
+1  A: 

Use std::bitset

#include <bitset>
#include <iostream>

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

    std::cout << bits[3] << std::endl;
}
Martin York
A couple of things worth mentioning here - bits[3] will give you the 4th bit - counting from the LSB to MSB. To put it loosely, it will give you the 4the bit counting from right to left. Also, sizeof(int) gives the number of characters in an int, so it would need to be std::bitset<sizeof(int)*CHAR_BITS> bits(temp), and bits[sizeof(int)*CHAR_BITS - 3] to test the 3rd bit counting from MSB to LSB, which is probably the intent.
plastic chris
Wow that was a wordy long winded comment for what is plainly obvious ;-) to anybody with enough skill to do bit twiddling.
Martin York
Yes, but I think the questioner (and people coming from google searches) might not have that skill, and your answer could mislead them.
plastic chris
A: 

For the low-level x86 specific solution use the x86 TEST opcode.

Your compiler should turn _bittest into this though...

jheriko