Difference between int and unsigned int in C [duplicate] - c

This question already has answers here:
Unsigned and Signed int and printf
(2 answers)
Closed 6 years ago.
I know that the range of unsigned int is 0<= I <= 2^32-1
However, when I type like this in C(visual 2015)
void main(){
unsigned int k = -10;
printf("%d",k);
}
then why computer print -10 on screen?? I think there should be error.

int stores signed numbers by default, which means they can go from -2,147,483,648 to 2,147,483,647 in range. An unsigned int means you won't be using negative numbers, so the range is much larger because you have freed up the left most bit in your number which is normally used to indicate that it is signed (negative) or not. So an unsigned int can go from 0 to 4,294,967,295. This applies to types like char as well, they normally go from -128 to 127, when unsigned, a char holds one byte exactly, or 0 to 255.
Visual Studio (and most compilers) should give you a warning for trying to store a signed value into an unsigned type.
When you used printf("%d",k) The %d is telling printf() to print out a signed int. So that is what it did. If you want printf() to print out an unsigned int than you needed to use printf("%u").

in hexadecimal form, -10 is 0xFFFFFFF6
unsigned int k = -10; means
unsigned int k = 0xFFFFFFF6;
and when printing this value if you say
printf("%d",k); the compiler will evaluate the value (0xFFFFFFF6) as integer because of the %d specifier. (check http://www.cplusplus.com/reference/cstdio/printf/ about the issue)
if you say printf("%u",k); the compiler will evaluate the value (0xFFFFFFF6) as unsigned integer and will print a value between 0-2^32-1

Related

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 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! :)

Why unsigned int stills signed? [duplicate]

This question already has answers here:
C Unsigned int providing a negative value?
(3 answers)
Closed 5 years ago.
I create an unsigned int and unsigned char. Then I assign the -10 value, and the char remains unsigned and gives me a value of 246, but the unsigned int takes the -10 value.
#include <stdio.h>
int main ()
{
unsigned char a;
unsigned int b;
a=-10;
b=-10;
printf("%d\t%d\n", a,b);
}
Compiling and executing I have this:
246 -10
I have no idea why the unsigned int stills signed, and why the char is unsigned.
Reading the book "The C programming language 2nd edition" I can see char can be unsigned by default depending on the machine.
(I'm running NetBSD as a operating system.)
Why the int is signed while I'm declaring as unsigned int, and why the char is taking the value 246?
Is this a compiler or system operating "feature" ?
This is undefined behavior when you pass unsigned integers to %d. Wrong format specifier is UB.
If you assign a negative value to an unsigned variable, it's fine and the value will be taken modulo UINT_MAX + 1 (or UCHAR_MAX + 1), so (-10) % (UCHAR_MAX + 1) = 256 - 10 = 246, and b is 4294967296 - 10 = 4294967286. Unsigned integral overflow is required to wrap-around.
When printf is interpreting these numbers, it finds 246 is suitable for %d, the format specifier for signed int, and 4294967286 is reinterpreted as -10. That's all.
When you assign -10 to an unsigned char variable, the value is reduced modulo UCHAR_MAX + 1, which results in 246 on your platform. Printing an unsigned char value using format %d is fine on most platforms. The value gets implicitly converted to int, which is the correct type for %d format. So, you see that 246 as you should.
When you assign -10 to an unsigned int variable, the value is reduced modulo UINT_MAX + 1, which results in some large value (depends on the range of unsigned int on your platform). Printing such large unsigned int value (greater than INT_MAX) using format %d leads to undefined behavior. The output is meaningless.
%d is the specifier used to print signed int, so it is not strange. Use %u instead.
http://www.cplusplus.com/reference/cstdio/printf/
And when you assign a negative value to an unsigned variable you will get overflow. That's why you get strange values.
printf("%d", a) means that will take the content of variable a and interpret it as a signed int.
Oh, and btw. You are causing undefined behavior which implies that there's really no reason to ask why something happens. Undefined behavior will always be undefined. Avoid it at all costs. Note that the only thing that is undefined is the printf statement. Assigning a value that's out of range to an unsigned variable is a defined behavior. However, the opposite is not true. int a = UINT_MAX will cause undefined behavior.

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

When will an unsigned int variable becomes negative

I was going through the existing code and when debugging the UTC time which is declared as
unsigned int utc_time;
I could get some positive integer every time by which I would be sure that I get the time. But suddenly in the code I got a negative value for the variable which is declared as an unsigned integer.
Please help me to understand what might be the reason.
Unsigned integers, by their very nature, can never be negative.
You may end up with a negative value if you cast it to a signed integer, or simply assign the value to a signed integer, or even incorrectly treat it as signed, such as with:
#include <stdio.h>
int main (void) {
unsigned int u = 3333333333u;
printf ("unsigned = %u, signed = %d\n", u, u);
return 0;
}
which outputs:
unsigned = 3333333333, signed = -961633963
on my 32-bit integer system.
When it's cast or treated as a signed type. You probably printed your unsigned int as an int, and the bit sequence of the unsigned would have corresponded to a negative signed value.
ie. Perhaps you did:
unsigned int utc_time;
...
printf("%d", utc_time);
Where %d is for signed integers, compared to %u which is used for unsigned. Anyway if you show us the code we'll be able to tell you for certain.
There's no notion of positive or negative in an unsigned variable.
Make sure you using
printf("%u", utc_time);
to display it
In response to the comment %u displays the varible as an unsigned int where as %i or %d will display the varible as a signed int.
Negative numbers in most (all?) C programs are represented as a two's complement of the unsigned number plus one. It's possible that your debugger or a program listing the values doesn't show it as an unsigned type so you see it's two's complement.

Resources