Value of x when s = x >> 31 and x = (s & ~x) | (~s & x); - c

If x was to equal 12 in a 32 bit scenario, x = multiple 0's into the lsb 0000 1100. If the above scenario were to run, I believe I would get 0000 1100. Am I wrong?
Along with that, what if I was to use x=-1? Wouldn't s = 1, but then does (s & ~x) look like (0001 & 0000) and (1110 & 1111)? Thanks
I thought that x=-1 would mean x>>31 would be like 0001 (output 1), but I don't know if the above is correct.

The typical implementation of a right shift of a signed integer is an arithmetic shift. Different implementations are unfortunately still allowed, though rare, and they're not relevant to understanding this code (it ignores such possibilities anyway). Two's complement integers are now mandatory (in C23: "The sign representation defined in this document is called two’s complement. Previous revisions of this document
additionally allowed other sign representation") so I'm not going to do the usual consideration of hypothetical integer representations that haven't been seen since the stone age.
By assumption the number of bits in an int is 32, so shifting an int right by 31 makes every bit of the result a copy of the sign bit. So if x was negative, s would be -1.
x = (s & ~x) | (~s & x) is a verbose way to spell out x ^= s. XORing x by 0 leaves it the same as before, XORing it by -1 inverts all the bits. Taking into account that s = x < 0 ? -1 : 0, effectively the computation does this:
if (x < 0)
x = ~x; // equivalent to: x = -x - 1;

Related

C - Saturating Signed Integer Multiplication with Bitwise Operators

Alright, so the assignment I have to do is to multiply a signed integer by 2 and return the value. If the value overflows then saturate it by returning Tmin or Tmax instead. The challenge is using only these logical operators (! ~ & ^ | + << >>) with no (if statements, loops, etc.) and only allowed a maximum of 20 logical operators.
Now my thought process to tackle this problem was first to find the limits. So I divided Tmin/max by 2 to get the boundaries. Here's what I have:
Positive
This and higher works:
1100000...
This and lower doesn't:
1011111...
If it doesn't work I need to return this:
100000...
Negative
This and lower works:
0011111...
This and higher doesn't:
0100000...
If it doesn't work I need to return this:
011111...
Otherwise I have to return:
2 * x;
(the integers are 32-bit by the way)
I see that the first two bits are important in determining whether or not the problem should return 2*x or the limits. For example an XOR would do since if the first to bits are the same then 2*x should be returned otherwise the limits should be returned. Another if statement is then needed for the sign of the integer for it is negative Tmin needs to be returned, otherwise Tmax needs to be.
Now my question is, how do you do this without using if statements? xD Or a better question is the way I am planning this out going to work or even feasible under the constraints? Or even better question is whether there is an easier way to solve this, and if so how? Any help would be greatly appreciated!
a = (x>>31); // fills the integer with the sign bit
b = (x<<1) >> 31; // fills the integer with the MSB
x <<= 1; // multiplies by 2
x ^= (a^b)&(x^b^0x80000000); // saturate
So how does this work. The first two lines use the arithmetic right shift to fill the whole integer with a selected bit.
The last line is basically the "if statement". If a==b then the right hand side evaluates to 0 and none of the bits in x are flipped. Otherwise it must be the case that a==~b and the right hand side evaluates to x^b^0x80000000.
After the statement is applied x will equal x^x^b^0x80000000 => b^0x80000000 which is exactly the saturation value.
Edit:
Here is it in the context of an actual program.
#include<stdio.h>
main(){
int i = 0xFFFF;
while(i<<=1){
int a = i >> 31;
int b = (i << 1) >> 31;
int x = i << 1;
x ^= (a^b) & (x ^ b ^ 0x80000000);
printf("%d, %d\n", i, x);
}
}
You have a very good starting point. One possible solution is to look at the first two bits.
abxx xxxx
Multiplication by 2 is equivalent to a left shift. So our result would be
bxxx xxx0
We see if b = 1 then we have to apply our special logic. The result in such a case would be
accc cccc
where c = ~a. Thus if we started with bitmasks
m1 = 0bbb bbbb
m2 = b000 0000
m3 = aaaa aaaa & bbbb bbbb
then when b = 1,
x << 1; // gives 1xxx xxxx
x |= m1; // gives 1111 1111
x ^= m2; // gives 0111 1111
x ^= m3; // gives accc cccc (flips bits for initially negative values)
Clearly when b = 0 none of our special logic happens. It's straightforward to get these bitmasks in just a few operations. Disclaimer: I haven't tested this.

how do I set up an if statement

How would I go about setting up an if statement using only the following bitwise operations:
!
~
&
^
|
&plus;
<<
>>
As an example: "if x is negative then add 15"
This would mean that if the input was x = 0xF0000000, then we would produce 0xF000000F. If the input was x = 0x00000004, we would produce 0x00000004.
You can add 15 to a number if it is negative, and 0 otherwise as follows. Shifting a negative number right will shift in 1's if the value is negative, and 0's otherwise. Shifting by 31 will fill the int with either 1's or 0's. ANDing by 0xF will set the summand to 15 if it is negative, and 0 otherwise, resulting in no change to x.
x += (x >> 31) & 0xF;
If you're worried about the implementation dependent behavior of shifting a signed number to the right. You can do the same thing with the following code, however you still are depending on a two's complement representation of the number. The shift results in 0 or 1, the multiplication scales the number to the appropriate value.
x += (((unsigned)x >> 31) * 0xF);

Convert two's complement to sign-magnitude

I need to convert from two's complement to sign-magnitude in C using only the operators
! ~ & ^ | + << >>
My approach is to find sign:
int sign = !(!(a>>31));
basically, if sign == 1 . I want to flip the number and add 1 else just want to display the number.
The thing is I can't use any loops, if statements etc.
This is what I'm working on:
int s_M = ((((a+1)>>31)^sign)+1)&sign;
any suggestions?
From http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs
int const mask = v >> 31;
unsigned int r = (v + mask) ^ mask;
Gives the absolute value (magnitude). If you wish to add the sign bit back simply mask and or the 32nd bit:
unsigned int s_M = r | (v & 0x80000000);
Or if you're looking for a one liner:
unsigned int s_M = ((v + (v >> 31)) ^ (v >> 31)) | (v & 0x80000000);
When you're converting from 2 complement, you should subtract 1, not add.
I'm not entirely sure what the output should be, but to obtain the magnitude you can do something like this:
int m = (a^(a>>31)) + sign;
Basically, shifting a negative number 31 bits to the right will make it all 1's, or 0xffffffff, which you can then use to xor the input number and make it positive. As you correctly noted sign needs to be added then for the correct result in that case.
If the input number was positive to begin with, the shift results in a zero and so the xor does nothing. Adding sign in that case also doesn't do anything, so it results in the input number.
To get the last bit you could use mask operation
int last_bit = 32 bit integer & 0x80000000
o/p may be 0 or 0x80000000
if it is 0 just display the given number else you have to perform the following operations to represent in signed magnitude
1) Subtract 1 from the number
2) perform 1s complement on the resultant ( that is negation ~)
3) Set the last bit of the resultant number
I mean ( ~ (num -`1) ) | 0x7fffffff
since your restricted not to use - operator. Perform the 2's complement on -1 and add it to the num.
To put it simple in one line
num & 0x80000000 ? printf("%d",(~(num+((~1)+1))) | 0x7fffffff) : printf("%d",num) ;

how to find left most 1 in a 32bit int in C [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Find the highest order bit in C
How can I write a C function that will generate a mask indicating the leftmost 1 in x.
Ex: 0xFF00 -> 0x8000, and 0x6600 -> 0x4000. So far:
int left1(unsigned x){}
I understand, 0xFF00 == 1111 1111 0000 0000..
and 0x6600 == 0110 0110 0000 0000.. but I'm stumped after that.
You can do this in two parts: first, use a technique called "bit smearing" to ensure that all the bits to the right of the first 1 are also 1:
x |= x >> 16;
x |= x >> 8;
x |= x >> 4;
x |= x >> 2;
x |= x >> 1;
At this point, an input of 0xFF00 will leave x equal to 0xFFFF, and an input of 0x6600 will leave x equal to 0x7FFF. We can then leave just the highest 1 set using:
x ^= x >> 1;
Count the number of times it takes to bit-shift to the right until you reach 1, then bit-shift that 1 to the left by that same count.
int ct=0;
while (x > 1) { ct++; x = x >> 1; }
x = x << ct;
One approach is to create a bitmask, and then right-shift the value.
That is, create a bitmask so that your integer is '1000....' or '0.....' - depending on whether that first bit is a 0 or a 1.
Then take that integer and right-shift it until it becomes the least-significant-bit, rather than the most-significant. As an example, 0b10000000 >> 8 is 1.
So first, depending on the size of your integer, you have to shift, well, however many bits are relevant.
Then you have to create the bitmask. Let's just take a 1-byte integer:
unsigned int i = 1 << 8 would create an integer i whose most significant bit is a 1.
Or you could use hex. You already know that 0xFF == 11111111. You can actually break it up further: 0xF0 == 11110000
Since 0xF == 1111 in binary, well, we will do the reverse. 1000 in binary is what, in hex? 1000 in binary is the number 8, which also happens to equal 0x8
So, for a single byte, the mask for the leftmost bit is 0x80.
Now! Apply this to 32 bits!
Good luck!

Need help understanding "getbits()" method in Chapter 2 of K&R C

In chapter 2, the section on bitwise operators (section 2.9), I'm having trouble understanding how one of the sample methods works.
Here's the method provided:
unsigned int getbits(unsigned int x, int p, int n) {
return (x >> (p + 1 - n)) & ~(~0 << n);
}
The idea is that, for the given number x, it will return the n bits starting at position p, counting from the right (with the farthest right bit being position 0). Given the following main() method:
int main(void) {
int x = 0xF994, p = 4, n = 3;
int z = getbits(x, p, n);
printf("getbits(%u (%x), %d, %d) = %u (%X)\n", x, x, p, n, z, z);
return 0;
}
The output is:
getbits(63892 (f994), 4, 3) = 5 (5)
I get portions of this, but am having trouble with the "big picture," mostly because of the bits (no pun intended) that I don't understand.
The part I'm specifically having issues with is the complements piece: ~(~0 << n). I think I get the first part, dealing with x; it's this part (and then the mask) that I'm struggling with -- and how it all comes together to actually retrieve those bits. (Which I've verified it is doing, both with code and checking my results using calc.exe -- thank God it has a binary view!)
Any help?
Let's use 16 bits for our example. In that case, ~0 is equal to
1111111111111111
When we left-shift this n bits (3 in your case), we get:
1111111111111000
because the 1s at the left are discarded and 0s are fed in at the right. Then re-complementing it gives:
0000000000000111
so it's just a clever way to get n 1-bits in the least significant part of the number.
The "x bit" you describe has shifted the given number (f994 = 1111 1001 1001 0100) right far enough so that the least significant 3 bits are the ones you want. In this example, the input bits you're requesting are there, all other input bits are marked . since they're not important to the final result:
ff94 ...........101.. # original number
>> p+1-n [2] .............101 # shift desired bits to right
& ~(~0 << n) [7] 0000000000000101 # clear all the other (left) bits
As you can see, you now have the relevant bits, in the rightmost bit positions.
I would say the best thing to do is to do a problem out by hand, that way you'll understand how it works.
Here is what I did using an 8-bit unsigned int.
Our number is 75 we want the 4 bits starting from position 6.
the call for the function would be getbits(75,6,4);
75 in binary is 0100 1011
So we create a mask that is 4 bits long starting with the lowest order bit this is done as such.
~0 = 1111 1111
<<4 = 1111 0000
~ = 0000 1111
Okay we got our mask.
Now, we push the bits we want out of the number into the lowest order bits so
we shift binary 75 by 6+1-4=3.
0100 1011 >>3 0000 1001
Now we have a mask of the correct number of bits in the low order and the bits we want out of the original number in the low order.
so we & them
0000 1001
& 0000 1111
============
0000 1001
so the answer is decimal 9.
Note: the higher order nibble just happens to be all zeros, making the masking redundant in this case but it could have been anything depending on the value of the number we started with.
~(~0 << n) creates a mask that will have the n right-most bits turned on.
0
0000000000000000
~0
1111111111111111
~0 << 4
1111111111110000
~(~0 << 4)
0000000000001111
ANDing the result with something else will return what's in those n bits.
Edit: I wanted to point out this programmer's calculator I've been using forever: AnalogX PCalc.
Nobody mentioned it yet, but in ANSI C ~0 << n causes undefined behaviour.
This is because ~0 is a negative number and left-shifting negative numbers is undefined.
Reference: C11 6.5.7/4 (earlier versions had similar text)
The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. [...] If E1 has a signed
type and nonnegative value, and E1 × 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
In K&R C this code would have relied on the particular class of system that K&R developed on, naively shifting 1 bits off the left when performing left-shift of a signed number (and this code also relies on 2's complement representation), but some other systems don't share those properties so the C standardization process did not define this behaviour.
So this example is really only interesting as a historical curiosity, it should not be used in any real code since 1989 (if not earlier).
Using the example:
int x = 0xF994, p = 4, n = 3;
int z = getbits(x, p, n);
and focusing on this set of operations
~(~0 << n)
for any bit set (10010011 etc) you want to generate a "mask" that pulls only the bits you want to see. So 10010011 or 0x03, I'm interested in xxxxx011. What is the mask that will extract that set ? 00000111 Now I want to be sizeof int independent, I'll let the machine do the work i.e. start with 0 for a byte machine it's 0x00 for a word machine it's 0x0000 etc. 64 bit machine would represent by 64 bits or 0x0000000000000000
Now apply "not" (~0) and get 11111111
shift right (<<) by n and get 11111000
and "not" that and get 00000111
so 10010011 & 00000111 = 00000011
You remember how boolean operations work ?
In ANSI C ~0 >> n causes undefined behavior
// the post about left shifting causing a problem is wrong.
unsigned char m,l;
m = ~0 >> 4; is producing 255 and its equal to ~0 but,
m = ~0;
l = m >> 4; is producing correct value 15 same as:
m = 255 >> 4;
there is no problem with left shifting negative ~0 << whatsoever

Resources