views:

217

answers:

4
+3  Q: 

Writing a C Macro

Hi, I have to write a macro that get as parameter some variable, and for each two sequential bits with "1" value replace it with 0 bit.

For example: 10110100 will become 10000100.
And, 11110000->00000000
11100000->100000000

I'm having a troubles writing that macro. I've tried to write a macro that get wach bit and replace it if the next bit is the same (and they both 1), but it works only for 8 bits and it's very not friendly...

P.S. I need a macro because I'm learning C and this is an exercise i found and i couldn't solve it myself. i know i can use function to make it easily... but i want to know how to do it with macros.

Thanks!

A: 
#define clear_bit_pairs(_x) ((_x)&~(((_x)&((_x)>>1))*3))
drawnonward
*Fabelhaft!* +1
susmits
It doesn't work if there's two adjacent bit-pairs. eg consider `10111100` (binary). The result should be `10000000`, but this algorithm gives `10101000`.
caf
A: 
#define clear_bit_pairs(_x) ((_x) ^ ((((_x)&((_x)>>1))<<1) | ((_x)&((_x)>>1))) )

This will work, but it does not pair up. If it finds the consecutive '1' it will just erase. for example 11100000 will become 00000000 because the first 111 are consecutive.

kalyan
+1  A: 
#define foo(x,i) (((x) & (3<<i)) == (3<<i)) ? ((x) - (3 << i)) : (x)
#define clear_11(x) foo(foo(foo(foo(foo(foo(foo(foo(foo(x,8),7),6),5),4),3),2),1),0)

This will do the job. However the expansion is quite big and compilation may take a while. So do not try this at work ;)

Danvil
Does this answer your question?
Danvil
A: 
#define foo(x) ({ \
    typeof(x) _y_ = x; \
    for(int _i_ = 0; _i_ < (sizeof(typeof(x)) << 3) + 1; _i_++) { \
        if((_y_ >> _i_ & 3) == 3) { \
            _y_ &= ~(3 << _i_); \
        } \
    } \
    _y_; \
})

This probably only works in GCC, since it uses inline statements. I haven't tested it, so it probably doesn't work at all. It is your job to make it work. :-)

The nice thing about this is that it will work with any integral type. It also doesn't rely on any external functions. The downside is that it is not portable. (And I realize that this is sort of cheating.)

Zifre
Anyone care to explain the downvote? Is this incorrect, or is just because this is cheating, sort of?
Zifre
The task is to do it completely with macros, not with functions. You just use the "#define TWIDDLE_BITS(var) twiddle_bits(var); Now all you have to do is to implement the function twiddle_bits(var);" approach.
Danvil
@Danvil: Well, not quite. This doesn't use any functions. Technically it is still entirely a macro. It's just not portable, and it's not just an expression.
Zifre