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

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.

Related

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.

How is a negative character stored in memory? [duplicate]

This question already has answers here:
Is char signed or unsigned by default?
(6 answers)
Closed 4 years ago.
#include <stdio.h>
int main()
{
int i = 23;
char c = -23;
if (i < c)
printf("Yes\n");
else
printf("No\n");
}
This segment of code executes the else block, but it executes the if block if we replace integer value with unsigned int i = 23.
Printing these values with %x results in
c=ffffffe9
i=17
My question here is how unsigned ints and char variables gets stored in memory?
When you compare two different types, your compiler will perform a cast to the most suitable one. But in your case, there is no good solution: either you loose the sign, or the precision.
What is happening is that your compiler is promoting your char to unsigned byte.
You should check if your char is negative prior comparing it to an unsigned to prevent this from happening.
Answering what you are actually asking, a negative character is stored in memory using its two's complement.
This should help you understand it a bit better: Signed to unsigned conversion in C - is it always safe?
"The int data type is signed and has a minimum range of at least -32767 through 32767 inclusive. The actual values are given in limits.h as INT_MIN and INT_MAX respectively.
An unsigned int has a minimal range of 0 through 65535 inclusive with the actual maximum value being UINT_MAX from that same header file."
Enjoy! :)

Query in left shifting of unsigned char [duplicate]

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.

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

Bitmasking with ~0 bitshifting using variables and constants [duplicate]

This question already has answers here:
Shifting a 32 bit integer by 32 bits
(2 answers)
Closed 9 years ago.
I am currently practicing bitshifting in order to test my knowledge and cement my abilities in C, though I am currently running into a bug with C. This code represents my problem:
#include <stdio.h>
int main() {
int p = 32;
printf("%d", ~0 << 32);
printf("%d", ~0 << p);
return 0;
}
~0 << 32 is 0 (all zero bits), ~0 << p is -1 (all 1 bits). Why does C interpret these statements differently?
Because the literal 0 is of type int. When you perform ~0 you end up with a negative int. Left-shifting a negative int is undefined behavior. And left shifting past the width of an integer is also undefined behavior.
So the expected result is: anything.
Why a particular case of undefined behavior causes a certain thing to happen is nothing to dwell on or try to understand. You wrote some bugs and then the program stopped behaving in a predictable manner, simple as that.

Resources