Query in left shifting of unsigned char [duplicate] - c

This question already has answers here:
Does bit shift automatically promote chars to int? [duplicate]
(2 answers)
Closed 5 years ago.
I have a question.
#include <stdio.h>
int main()
{
unsigned char i = 0x80;
printf("%d\n",i<<1);
return 0;
}
In above program, unsigned char is assigned 0x80(i.e 128). For i<<1, I am getting the value of 256. My doubt here is i = 1000 0000 binary, but how can i<<1 get the value 256 ? why not 0, as (1000 0000)<<1 1 will knocked off ?

If a variable with a rank lower than int is used in an expression, such as char or unsigned char, it is promoted to an int before the expression is evaluated.
So your unsigned char value 0x80 is converted to the int value 0x80 and the << operator is applied to that. So what was the high order bit is no longer the high order bit, so it doesn't get shifted out.

Related

signed char doesn't overflow when result of arithmetic operation is assigned. But when a numeric value is assigned, it overflows. Please explain [duplicate]

This question already has answers here:
Implicit type promotion rules
(4 answers)
char and the usual arithmetic conversion rules
(5 answers)
Closed 12 months ago.
Consider following C code
int main() {
signed char result = 129;
printf("%d", result);
return 0;
}
Assuming char is 8 bit, 129 causes overflow, hence result of printf will be -127. I'm clear with this part.
But when i try the following:
int main() {
signed char a=100,b=3;
signed char c= 4;
signed char result = a*b/c;
printf("%d", result);
return 0;
}
Then as per the convention, as a and b are signed char, a*b will be a signed char. Hence, 300 will overflow, so, only LSB(least significant 8 bits should be considered). This will make it 44 and when divided by 4, it should print 11 and not 75. I'm confused here.

why is 00000000 - 00000001 = 11111111 in C unsigned char data type? [duplicate]

This question already has answers here:
Question about C behaviour for unsigned integer underflow
(3 answers)
Closed 3 years ago.
I observed that, when a unsigned char variable stores the value 0 (000000002) and it gets decremented by 1 (000000012), the variable value turns into 255 (111111112), which is the highest value that a unsigned char variable can hold.
My question is: why 000000002 - 000000012 turns into 111111112? (I want to see the arithmetic behind it)
The C code in which i observed it was this one:
#include <stdio.h>
main(){
unsigned char c = 0;
unsigned char d = c - 1;
printf("%d\n%d", c, d);
}
When it runs, the following output is shown:
0
255
See here:
Unsigned integer arithmetic is always performed modulo 2n where n is
the number of bits in that particular integer. E.g. for unsigned int,
adding one to UINT_MAX gives ​0​, and subtracting one from ​0​ gives
UINT_MAX.
So in your example, since unsigned char is usually 8 bit, you get 28-1 = 255.

Information lost with type conversion in C [duplicate]

This question already has answers here:
assigning 128 to char variable in c
(3 answers)
Closed 4 years ago.
#include <stdio.h>
int main(int argc, char const *argv[])
{
int x = 128;
char y = x;
int z = y;
printf("%d\n", z);
return 0;
}
i don't understand why this program prints -128.
i have tried to convert 128 in binary base but i'm still confused on how the C compiler convert int to char and char to int.
Note : in my machine sizeof(char) = 1 and sizeof(int) = 4
Assuming a char is signed and 8 bits, its range is -128 to 127 which means the value 128 is out of range for a char. So the value is converted in a implementation-defined manner. In the case of gcc, the result is reduced modulo 28 to become in range.
What this basically means is that the low-order byte of the int value 128 is assigned to the char variable. 128 in hex as 32-bit is 0x00000080, so 0x80 is assigned to y. Assuming 2's compliment representation, this represents the value -128. When this value is then assigned to z, which is an int, that value can be represented in an int, so that's what gets assigned to it, and its representation is 0xffffff80.
C standard does not specify whether char is signed or unsigned. In fact, assigning a char type a value outside of the basic execution character set is implementation defined. You can probably use the macros in <limits.h> to verify.
I suspect on your system char is signed, which makes the max value 127. Signed interger overflow is undefined. So no guarantess on the output. In this case, it looks like it wraps around.

how the computer convert a number of signed int to unsigned int [duplicate]

This question already has answers here:
int to unsigned int conversion
(7 answers)
Closed 6 years ago.
I am wondering why this code will output -5 , since they are of different types, and -5 is a very large in unsigned considering 2's complement
#include <stdio.h>
int main()
{
unsigned int x = -5; //
printf("%d", x);
}
I am very confused, how a signed int be converted into unsigned? thanks!
The initial conversion occurs when -5 is assigned to an unsigned int. At that point you have, as suggested, a very large number (the actual value depending on the number of bits in int on your machine).
The second "conversion" is really an interpretation. printf is asked to take a set of bits and print them out as though they represent an unsigned integer value. This is why the output is -5

How can 256 be represented by a char? [duplicate]

This question already has answers here:
what is char i=0x80 and why overflow did not happen in bit shifting
(6 answers)
Closed 9 years ago.
I ran the following code in xcode in to my surprise the answer was 256.
Since char is only 8 bits long i expected this to be 0.
Dumping the 1 in the 8 place.
Can someone explain what is going on?
int main()
{
unsigned char i = 0x80;
printf("%d\n", i<<1);
return 0;
}
It is being promoted to an integer, which can contain the value of 256 just fine. A cast to unsigned char will give you the result you expected:
printf("%d\n", (unsigned char)(i<<1) );
It is being promoted to an integer when you do i << 1. For example, SHL works on 32 bit words (even though your c type is 8 bit) in x86 so the shifted bit isn't discarded out of the 32 bit register. When you print this region with with "%d", you get 256. If you want to left shift with unsigned char, you can always do (i << x) & 0xff.
In this case, what is happening is that the intermediate result of i<<1 is an integer, which can represent 256.

Resources