condition check replaced by bitwise operator [duplicate] - c

This question already has answers here:
Check if a number x is positive (x>0) by ONLY using bitwise operators in C
(12 answers)
Closed 7 years ago.
int x1 =-2 ;//any value
if(x1 < 0)
x1 = 0;
I am trying by using bitwise operator
int result = !(x1 >> 31) & (((~x1 + 1) >> 31) & 1);
x1 = result !=0 ? x1:result;
I don't want to use the conditional operator to explore more use of binary operator .There is no any other intension behind this .If any way is there please let me know .
Is there any way to do so ??

Assuming 32 bit integer and two's compliment, would the following be OK?
unsigned int x = (unsigned int)-2;
x &= (x >> 31) - 1;
I used unsigned because according to the standard
The result of E1 >> E2 is E1 right-shifted E2 bit positions. .... If E1 has a signed type and a negative value, the
resulting value is implementation-defined.

Related

bits shift exceeding width of type in C [duplicate]

This question already has answers here:
warning: left shift count >= width of type
(6 answers)
Closed 1 year ago.
I have a uint64_t variable called vpn and I'm trying to get its left 9 bits.
I know vpn is 45 bits long, so I tried the following:
uint64_t nineMSB = (vpn & (511 << 36)) >> 36;
but I get the following warning:
left shift count >= width of type
Why is that? 511 is 9 ones in binary so 511 << 36 should give me 45 bits, and I'm doing an AND with a uint64_t so the result should not exceed 64 bits..
Thank you!
The constant 511 has type int. Your system most likely has a 32-bit int, so this means you're shifting a value by an amount larger than its bit length. Doing so triggers undefined behavior.
This is dictated by section 6.5.7p3 of the C standard regarding bitwise shift operators:
The integer promotions are performed on each of the operands. The type
of the result is that of the promoted left operand. If the
value of the right operand is negative or is greater than or
equal to the width of the promoted left operand, the behavior is
undefined.
You can fix this by using the ULL suffix on the constant, which will give it type unsigned long long which is guaranteed to be at least 64 bits in length.
uint64_t nineMSB = (vpn & (511ULL << 36)) >> 36;
integer constants without any suffixes or prefixes have type of int. On many systems int is 32bit long, but it can also be only 16bits long (avr port).
uint64_t foo(uint64_t vpn)
{
uint64_t nineMSB = (vpn & (511ULL << 36)) >> 36;
return nineMSB;
}
uint64_t foo1(uint64_t vpn)
{
uint64_t nineMSB = (vpn & ((uint64_t)511 << 36)) >> 36;
return nineMSB;
}

Unexpected bitshift behavior in C [duplicate]

This question already has answers here:
What happens when you bit shift beyond the end of a variable?
(3 answers)
Closed 3 years ago.
I am currently trying to extract some bits from an address called addr with a 32 bit mask called mask into another variable called result as follows
int addr = 7;
int x = 0;
uint32_t mask = 0xFFFFFFFF;
result = addr & (mask >> (32 - x));
I am expecting result to be 0 when x = 0, and this is confirmed on online bitshift calculators. however in C code, result is 1. Why is that?
You're performing an illegal bitshift.
Shifting by a value greater or equal than the size in bits of the left operand results in undefined behavior. This is documented in section 6.5.7p3 of the C standard:
The integer promotions are performed on each of the operands. The type
of the result is that of the promoted left operand. If the value of
the right operand is negative or is greater than or equal to the width
of the promoted left operand, the behavior is undefined.
This means you need to check the value of x, and if it is 0 then just use 0 for the bitmask.
int x = 0;
uint32_t mask = 0xFFFFFFFF;
...
if (x == 0) {
result = 0;
} else {
result = addr & (mask >> (32 - x));
}
From the C standard (6.5.7 Bitwise shift operators)
3 The integer promotions are performed on each of the operands. The
type of the result is that of the promoted left operand. If the value
of the right operand is negative or is greater than or equal to the
width of the promoted left operand, the behavior is undeļ¬ned

How to multiply by three sixteenths [duplicate]

This question already has answers here:
In C bits, multiply by 3 and divide by 16
(5 answers)
Closed 8 years ago.
I need to multiply a number by 3/16, rounding to zero using only bitwise operations such as ! ~ & ^ | + << >>. So far I have the following, the only problem is it doesn't work when the number is negative, it always rounds down rather than to zero. I know there should be bitwise if statement that if x is negative then add 15. But I dont know how to implement it, any help is appreciated.
int ezThreeSixteenths(int x) {
int times_two = x << 1;
int times_three = times_two + x;
int divide_eight = times_three >> 4;
int a = 0b11111111;
int a1 = a << 8;
int a2 = a << 16;
int a3 = 0b11111 << 24;
int mask = a | a1 | a2 | a3;
int final = divide_eight & mask;
return final;
}
If you have a function that you are satisfied works when it's positive, test the MSB to detect a negative bit, if so take the two's complement (you don't say whether you can use - as well as + but you can use ^ and +), run your function, then take the two's complement again.
Use twos complement to convert a negative number to a positive number. Then when you're done convert the positive number back to a negative one?

Moving a "nibble" to the left using C

I've been working on this puzzle for awhile. I'm trying to figure out how to rotate 4 bits in a number (x) around to the left (with wrapping) by n where 0 <= n <= 31.. The code will look like:
moveNib(int x, int n){
//... some code here
}
The trick is that I can only use these operators:
~ & ^ | + << >>
and of them only a combination of 25. I also can not use If statements, loops, function calls. And I may only use type int.
An example would be moveNib(0x87654321,1) = 0x76543218.
My attempt: I have figured out how to use a mask to store the the bits and all but I can't figure out how to move by an arbitrary number. Any help would be appreciated thank you!
How about:
uint32_t moveNib(uint32_t x, int n) { return x<<(n<<2) | x>>((8-n)<<2); }
It uses <<2 to convert from nibbles to bits, and then shifts the bits by that much. To handle wraparound, we OR by a copy of the number which has been shifted by the opposite amount in the opposite direciton. For example, with x=0x87654321 and n=1, the left part is shifted 4 bits to the left and becomes 0x76543210, and the right part is shifted 28 bits to the right and becomes 0x00000008, and when ORed together, the result is 0x76543218, as requested.
Edit: If - really isn't allowed, then this will get the same result (assuming an architecture with two's complement integers) without using it:
uint32_t moveNib(uint32_t x, int n) { return x<<(n<<2) | x>>((9+~n)<<2); }
Edit2: OK. Since you aren't allowed to use anything but int, how about this, then?
int moveNib(int x, int n) { return (x&0xffffffff)<<(n<<2) | (x&0xffffffff)>>((9+~n)<<2); }
The logic is the same as before, but we force the calculation to use unsigned integers by ANDing with 0xffffffff. All this assumes 32 bit integers, though. Is there anything else I have missed now?
Edit3: Here's one more version, which should be a bit more portable:
int moveNib(int x, int n) { return ((x|0u)<<((n&7)<<2) | (x|0u)>>((9+~(n&7))<<2))&0xffffffff; }
It caps n as suggested by chux, and uses |0u to convert to unsigned in order to avoid the sign bit duplication you get with signed integers. This works because (from the standard):
Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.
Since int and 0u have the same rank, but 0u is unsigned, then the result is unsigned, even though ORing with 0 otherwise would be a null operation.
It then truncates the result to the range of a 32-bit int so that the function will still work if ints have more bits than this (though the rotation will still be performed on the lowest 32 bits in that case. A 64-bit version would replace 7 by 15, 9 by 17 and truncate using 0xffffffffffffffff).
This solution uses 12 operators (11 if you skip the truncation, 10 if you store n&7 in a variable).
To see what happens in detail here, let's go through it for the example you gave: x=0x87654321, n=1. x|0u results in a the unsigned number 0x87654321u. (n&7)<<2=4, so we will shift 4 bits to the left, while ((9+~(n&7))<<2=28, so we will shift 28 bits to the right. So putting this together, we will compute 0x87654321u<<4 | 0x87654321u >> 28. For 32-bit integers, this is 0x76543210|0x8=0x76543218. But for 64-bit integers it is 0x876543210|0x8=0x876543218, so in that case we need to truncate to 32 bits, which is what the final &0xffffffff does. If the integers are shorter than 32 bits, then this won't work, but your example in the question had 32 bits, so I assume the integer types are at least that long.
As a small side-note: If you allow one operator which is not on the list, the sizeof operator, then we can make a version that works with all the bits of a longer int automatically. Inspired by Aki, we get (using 16 operators (remember, sizeof is an operator in C)):
int moveNib(int x, int n) {
int nbit = (n&((sizeof(int)<<1)+~0u))<<2;
return (x|0u)<<nbit | (x|0u)>>((sizeof(int)<<3)+1u+~nbit);
}
Without the additional restrictions, the typical rotate_left operation (by 0 < n < 32) is trivial.
uint32_t X = (x << 4*n) | (x >> 4*(8-n));
Since we are talking about rotations, n < 0 is not a problem. Rotation right by 1 is the same as rotation left by 7 units. Ie. nn=n & 7; and we are through.
int nn = (n & 7) << 2; // Remove the multiplication
uint32_t X = (x << nn) | (x >> (32-nn));
When nn == 0, x would be shifted by 32, which is undefined. This can be replaced simply with x >> 0, i.e. no rotation at all. (x << 0) | (x >> 0) == x.
Replacing the subtraction with addition: a - b = a + (~b+1) and simplifying:
int nn = (n & 7) << 2;
int mm = (33 + ~nn) & 31;
uint32_t X = (x << nn) | (x >> mm); // when nn=0, also mm=0
Now the only problem is in shifting a signed int x right, which would duplicate the sign bit. That should be cured by a mask: (x << nn) - 1
int nn = (n & 7) << 2;
int mm = (33 + ~nn) & 31;
int result = (x << nn) | ((x >> mm) & ((1 << nn) + ~0));
At this point we have used just 12 of the allowed operations -- next we can start to dig into the problem of sizeof(int)...
int nn = (n & (sizeof(int)-1)) << 2; // etc.

What is the meaning of this?

hi guys can you explain what does that greater than sign do in the follwing code
if (header->mode > forceMode)
{
*rate >>= (header->mode - forceMode); //What does this mean >>=
*granule_frame_size <<= (header->mode - forceMode); //What does this mean <<=
}
While all the answers above are correct, it's possible you might still not understand it. You will need to understand binary.
Imagine you have the expression
7 << 2
That means "Convert 7 into binary, then shift all the bits left 2 times."
So 7 is 00000111
shifted left twice (and inserting zeros) yeilds:
00011100
This is equal to 28.
So if the variable A is 7, and B is 2, then:
A <<= B;
Leaves A equal to 28;
>>= is the right-shift assignment operator. x >>= y is equivalent to x = x >> y (with the caveat that #bdonlan points out below).
The << and >> operators are traditionally thought of bitwise because that's how they're implemented, but as far as the C language is concerned, they are arithmetic operators (not bitwise operators) equivalent to multiplication and division by the corresponding power of 2. That is, x<<y is x*2^y and x>>y is x/2^y (with integer truncation), where by ^ I mean "raised to the power" and not "xor". They are only defined for positive values of x, and like all arithmetic operators, << has undefined behavior for signed operands if the result overflows.

Resources