What is the meaning of this? - c

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.

Related

Is this bit operator code is side effects (term used in K&R C book) or machine dependent processing instruction?

Here is two code that appears to be doing same thing,but It does not. These two different when run and compared output with tracing gives confusion as it appears that the 1st code processing is machine dependent code.
Please read the two codes
Code 1:--
unsigned char c=(((~0 << 3) >> 4) << 1);
printf("%d", c);
Output:-- 254
Code 2:--
unsigned char c=(~0 << 3);
c >>= 4;
c <<= 1;
printf("%d", c);
Output:-. 30
The Output of the above code is different.
Not only this code (1st code) giving confusion but all types of code involving single line multiple bitwise shift operator gives unexpected results.
2nd code is doing correct.
Please run this code on your machine and verify above output
AND / OR
Explain why these output are not same.
OR
Finally we have to learn that we should not apply multiple bitwise shift operator in our code.
Thanks
~0 << 3 is always a bug, neither example is correct.
0 is of type int which is signed.
~0 will convert the binary contents to all ones: 0xFF...FF.
When you left shift data into the sign bit of a signed integer, you invoke undefined behavior. Same thing if you left shift a negative integer.
Conclusion: neither example has deterministic output and both can crash or print garbage.
First, ~0 << 3 invokes undefined behavior because ~0 is a signed integer value with all bits set to 1 and you subsequently left shift into the sign bit.
Changing this to ~0u << 3 prevents UB but prints the same result, so the question is why.
So first we have this:
~0u
Which has type unsigned int. This is at least 16 bits so the value is:
0xffff
Then this:
`~0u << 3`
Gives you:
0xfff8
Then this:
((~0 << 3) >> 4)
Gives you:
0x0fff
And this:
(((~0 << 3) >> 4) << 1)
Gives you:
0x1ffe
Assigning this value to an unsigned char effectively trim it down to the low order byte:
0xfe
So it prints 254.
Now in the second case you start with this:
unsigned char c = (~0 << 3);
From above, this assigns 0xfff8 to c which gets truncated to 0xf8. Then >> 4 gives you 0x0f and << 1 gives you 0x1e which is 30.
I compiled (with x86-64 gcc 9.1) these two lines:
int main() {
unsigned char e=(~0 << 1);
unsigned char d=(((~0 << 3) >> 4) << 1);
}
And I got the following assembly output:
main:
push rbp
mov rbp, rsp
mov BYTE PTR [rbp-1], -2
mov BYTE PTR [rbp-2], -2
mov eax, 0
pop rbp
ret
As you can see, both lines are converted to the same instruction mov BYTE PTR [rbp-1], -2. So, it seems the compiler is making an optimization with your first code.
Thanks to Thomas Jager for his answer (given on question comment)
The solution is simple.
In 1st code, the bit manipulation is performed with taking operand as signed char.
Because of this, two complement binary number continue to change its bit pattern as the bit manipulation is in process. After that the result two complement number is converted to positive number before assigning to unsigned variable c. Hence Result is 254 finally.
The question is to explain why two code output is different.
We all know Code 2nd is working good.
Hence i explain only why Code 1 is working incorrectly.
1st Code : -
unsigned char c=(((~0 << 3) >> 4) << 1);
printf("%d", c);
The tracing of 1st code are as follows : -
Step 1: ~0 -----> -1 ----(binary form)----> 11111111 with sign bit 1 (means negative)
Step 2: (sign bit 1)11111111 << 3 -----shifting to left----> (sign bit 1)11111000
Step 3 ***: (sign bit 1)11111000 >> 4 ----shifing to right-----> (sign bit 1)11111111
*[*** - The left most bits is 1 in Result because of sign extension
Sign bit 1 retain its bit to 1 but right shifting the number will append 1 to
left most bits without modify sign bit to 0 .
Hence all left most bit append to 1 because sign bit 1 is supplying this 1 to
left most bits while right shifting ]*
Step 4: (sign bit 1)11111111 << 1 ---shifting to left---> (sign bit 1)11111110
Step 5: two complement number (sign bit 1)11111110 converted to positive number
by deleting only sign bit to 0.
Step 6: Result : (sign bit 0)11111110 ---decimal equivalent---> 254
I only just explain his answer.
Thanks to all for giving effort for answer of this question.

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 does << and >> operator works in C? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
void main()
{
int x=5;
printf("%d%d%d \n",x,x<<2,x>>2);
}
<< and >> are the left and right shift operators, respectively.
These operators apply a bitwise shift to the left operand; the number of positions to shift is determined by the right operand.
In this example, we have three expressions: x, (x << 2), and (x >> 2).
For x = 5, the values of these expressions are:
Expr. Dec. Value Binary Value (Top 24 bits (all zero) ommitted)
x 5 00000101
x << 2 20 00010100
x >> 2 1 00000001
Notice that a left shift of one position effectively multiplies an unsigned int by 2; similarly, right shift divides an unsigned integer by 2. Also, whether the shift is arithmetic or logical (i.e. sign sensitive) is implementation dependent.
They are left shift and right shift operators. Bitwise operations
<< shifts to the left and >> to the right. So in your example x>>2 throws away the last two bits of the 5 (101 in binary). That would be 1.
5<<2 is 20 (10100 in binary).
Those are logical shift operators, with <<X meaning Left Shift x times, and >>X meaning Right Shift x times.
If you have a number like 14, it is stored as a the series of bits "00001110". When you left shift this number 1 time, the stored bit sequence changes to "00011100", and you get the number 28. Shifting a number left is the same as multiplying it by 2, while shifting it right is the same as dividing by 2. In this example, any digits on the left side that would get pushed into a "9th" spot simply disappear since only 8 bits are available. The same rules apply for the right shift.
x<<y means x*2^y (^ meaning "to the power of") and x>>y means x/2^y. They are well-defined only for positive x, only for y smaller than the width of the type of x in bits, and if x is signed, only when the result does not overflow.
These are basically bitwise shift operators.
The left shift operator causes the bit pattern in the first operand to be shifted to the left by the number of bits specified by the second operand.
The value of a left-shift expression (x << y) is x * (2^y)
00010111 LEFT-SHIFT by 1 = 00101110
The right shift does the same thing but shifts the bit pattern to the right.
The value of a right-shift expression x >> y is x / (2^y)
00010111 RIGHT-SHIFT by 1 = 00001011

Logical, arithmetical bitwise shifts

Seeking to clarify something.
It is my understanding that with regard to arithmetical, logical bitwise shifts:
<< work the same for both
>> shifts differ in that logical shift will always pad byte with 0, whereas arithmetical shift will pad it with the sign bit.
How can I differentiate this using C?
From what I understand, actual operators are the same <<,>>
How would command differ between:
int i=1;
printf ("%d\n", i >> 1); // logical shift
int j=1;
printf ("%d\n", j >> 1); // arithmetical shift
Please let me know,
In case of nonnegative numbers, both kinds of right-shifts are the same. The difference appears only when the number to shift is negative.
Actually the C standard does not specify when should >> perform logical or arithmetic shift when the number is negative, but typically, it performs arithmetic shift. To perform logical shift, the number must be cast to the corresponding unsigned type, for example:
int x = -2;
int y = x >> 1; // arithmetic shift.
assert (y == -1);
int z = (unsigned)x >> 1; // logical shift.
assert (z == 0x7FFFFFFF);

Right shift (Division) -> ROUND TOWARD ZERO

I am doing this..
value >> 3;
It is always going toward negative side.How do I round toward zero with right shift division?
Gez, the answers were pretty bad ; you want to solve that without branching, but without breaking your positive numbers either.
Here it is :
(int)(value+(((unsigned)value)>>31)) >> 3
The cast to (unsigned) is required to perform a logical shift and obtain just the sign bit, then we need to cast back to (int) to perform an arithmetic right shift.
The code above made the assumption that your int data type is 32 bits, you should of course use data types such as int32_t in such cases.
Do something conditionally depending on whether your value is positive or negative.
if( value < 0 ) {
-((-value) >> 3);
}
else {
value >> 3;
}
Try the following expression instead:
(value < 0) ? -((-value) >> 3) : value >> 3;
That will force a negative number to be positive first so that it round towards zero, then changes the result back to negative.
This may cause issues for the minimum integer under two's complement notation (not ones' complement or sign/magnitude) but you could put a separate check in to catch that first.
Or (and this is probably preferable) you could just stop trying to divide by eight with a right shift altogether, instead choosing:
value = value / 8;
Then let your compiler choose the best way of doing that. You should be coding to specify intent rather than trying to optimise (needlessly, unless you have a truly brain-dead compiler).
I do this:
(value + 4) >> 3
Add 7 to the number if it is negative in order to round to zero.
This is how you do that:
int mask = x >> 31;
x = (x + (7 & mask)) >> 3;
You are encountering 'signed' shifting, when what you seem to want is unsigned shifting. Try casting it to unsigned first, like this
x = ((unsigned) x) >> 3;
.. or you could just use division.

Resources