Page 1 of 2

Performing bitwise operations in C

Posted: Thu Apr 15, 2004 9:14 pm
by Jonathan
So I want to say

Code: Select all

int x, y;
y = x[0] ^ x[2] ^ x[17];
There's not a snappy way to write that in C, is there? I'm going to have to do

Code: Select all

y = x & 0x1 ^ x & 0x100 ^ x & 0x100000000000000000;
aren't I?

Posted: Thu Apr 15, 2004 9:38 pm
by VLSmooth
Assuming x[n] is the nth bit (not an array entry), I think so. :(

Posted: Thu Apr 15, 2004 10:13 pm
by quantus
Your constants aren't supposed to be more than 8 bits. Your compiler may still handle it ok, but it's still going to be compiled as something like the following. Besides, it's better for readability to do this as well so someone doesn't have to count all the damn 0's.

Code: Select all

int a,b,c;
c = 0x1;
y = x & c ^ x & 0x4 ^ x & (c<<17);
editted to fix binary and hex confusion

Posted: Thu Apr 15, 2004 10:21 pm
by VLSmooth
Might as well be consistent then. Using a combination of a literal (0x100) and a variable isn't very pretty. Why not just:

Code: Select all

int x, y;
y = x & 0x1 ^ x & 0x100 ^ x & (1<<17)
and screw the extra unnecessary variable?

Posted: Thu Apr 15, 2004 10:24 pm
by Jonathan

Code: Select all

int TWOTOTHE(int x) {
  return 1<<x;
}

y = x&TWOTOTHE(1) ^ x&TWOTOTHE(2) ^ x&TWOTOTHE(17);
I went this route.

I'm surprised no one complained that I mixed binary and hexadecimal when initially describing the problem. ::sniff:: I'm so proud of you!

Posted: Thu Apr 15, 2004 10:40 pm
by VLSmooth
Hex, Binary, only a power of 4 off, no biggie 8)

Posted: Thu Apr 15, 2004 11:01 pm
by quantus
Dwindlehop wrote:I'm surprised no one complained that I mixed binary and hexadecimal when initially describing the problem. ::sniff:: I'm so proud of you!
Wow, you're right, totally missed that. As for being proud of crappy debugging skillz, you must be smoking something. Anyways, I blame it on understanding your intent and leaving implementation up to the user (ie. you).

Posted: Thu Apr 15, 2004 11:16 pm
by Jonathan
quantus wrote:
Dwindlehop wrote:I'm surprised no one complained that I mixed binary and hexadecimal when initially describing the problem. ::sniff:: I'm so proud of you!
Wow, you're right, totally missed that. As for being proud of crappy debugging skillz, you must be smoking something. Anyways, I blame it on understanding your intent and leaving implementation up to the user (ie. you).
I think understanding my intent and leaving well enough alone is something we can all be proud of.

Posted: Fri Apr 16, 2004 11:54 pm
by Jonathan
Whoops. There's a problem with all the code in this thread.

Code: Select all

int TWOTOTHE(int x) {
  return 1<<x;
}

y = x&TWOTOTHE(1) ^ x&TWOTOTHE(2) ^ x&TWOTOTHE(17);
To take mine as an example, y will have the value of x[1]*2^1 + x[2]*2^2 + x[17]*2^17;, which is most definitely not want I want.

I'm going to do this instead.

Code: Select all

int NTHBIT(int x, int n) {
  return (1<<n & x)>>n;
}
Bug sightings or more intelligent solutions welcome.

Posted: Sat Apr 17, 2004 12:57 am
by quantus
ok, you suck. You can't even represent what you want correctly. The new function you wrote barely makes sense in context of what you originally wrote. What you want is a bool essentially? And you want y to be is the xor of those 3 bools? Ok, then what you have now would work most of the time.

There is a bug though. What you don't realize is that >> shifts in x[31]. In most cases you're zeroing out this bit from the bit mask, but if you actually want x[31] and it's 1, you're not going to get what you expect. Completely correct code would be as follows:

Code: Select all

int NTHBIT(int x, int n) { 
  return ((1<<n & x)>>n)&1; 
}

Posted: Sat Apr 17, 2004 1:01 am
by quantus
Oh, and this is what you get for being proud of us being not overly picky. By trying to understand what you meant, we ignored the complete lack of consistency in your original examples of psuedo-code.

Posted: Sat Apr 17, 2004 1:05 am
by Jonathan
I have dishonored my warrior clan.

Yes, I want the xor of three bools. In my actual implementation, I'm using unsigned long longs instead of ints. I went ahead and took the least significant bit only, though.

Posted: Sat Apr 17, 2004 1:16 am
by quantus
long longs? like 64-bit longs?

Posted: Sat Apr 17, 2004 1:24 am
by Jonathan
That's the definition of long long on Intel hardware, yes.

Posted: Tue Apr 18, 2006 10:54 pm
by Jonathan
Here's the perl equivalent, so I never have to think again:

Code: Select all

sub bit_slice() {
  $val = shift;
  $pos = shift;
  return ((1<<$pos & $val)>>$pos)&1;
}
Now the question is, how to return a range of bits? I'm talking about the Verilog equivalent of "signal[9:3]".

Re: Performing bitwise operations in C

Posted: Wed Apr 19, 2006 4:21 am
by quantus
When did:
Dwindlehop wrote:

Code: Select all

int x, y;
y = x[0] ^ x[2] ^ x[17];
become:
Dwindlehop wrote:

Code: Select all

int TWOTOTHE(int x) {
  return 1<<x;
}

y = x&TWOTOTHE(1) ^ x&TWOTOTHE(2) ^ x&TWOTOTHE(17);
notice that the first index became 1 instead of 0... Looks to be Jonathan's error...

Posted: Wed Apr 19, 2006 6:17 am
by quantus
Try:

Code: Select all

sub bit_slice() {
  $val = shift;
  $pos1 = shift;
  $pos2 = ( $#_ >= 0 ) ? shift : $pos1;
  warn "YOU SUCK!!!" if ( $pos1 > 31 || $pos2 > 31 || $pos1 > $pos2 );
  my $mask = (1<<($pos2-$pos1+1))-1;
  return ( $val >> $pos1 ) & $mask;
}
editted to set $pos2 = $pos1 if there is no 3rd argument

Re: Performing bitwise operations in C

Posted: Wed Apr 19, 2006 7:43 pm
by Jonathan
quantus wrote:Looks to be Jonathan's error...
If you're trying to point out that I suck, you won't get any arguments from me.

Posted: Wed Apr 19, 2006 9:45 pm
by quantus
Have you really done this so often over the last 2 years that you've needed to keep a final solution somewhere?

Posted: Wed Apr 19, 2006 11:11 pm
by Jonathan
Happens more than once, yeah. Usually it's generating cache state.