Unsigned hexadecimal constant in C? - c

Does C treat hexadecimal constants (e.g. 0x23FE) and signed or unsigned int?

The number itself is always interpreted as a non-negative number. Hexadecimal constants don't have a sign or any inherent way to express a negative number. The type of the constant is the first one of these which can represent their value:
int
unsigned int
long int
unsigned long int
long long int
unsigned long long int

It treats them as int literals(basically, as signed int!). To write an unsigned literal just add u at the end:
0x23FEu

According to cppreference, the type of the hexadecimal literal is the first type in the following list in which the value can fit.
int
unsigned int
long int
unsigned long int
long long int(since C99)
unsigned long long int(since C99)
So it depends on how big your number is. If your number is smaller than INT_MAX, then it is of type int. If your number is greater than INT_MAX but smaller than UINT_MAX, it is of type unsigned int, and so forth.
Since 0x23FE is smaller than INT_MAX(which is 0x7FFF or greater), it is of type int.
If you want it to be unsigned, add a u at the end of the number: 0x23FEu.

Related

Why do we use suffix in c variables?

What is the difference between these two declarations?
long int n=12;
long int n=12l;
int n=12l;
and
How does an unsigned variable store signed values?
unsigned int number=-13;
What is the difference between these declarations?
long int n=12;
An int value 12 is assigned to the long variable n.
long int n=12l;
A long value 12l is assigned to the long variable n.
int n=12l;
A long value 12l is assigned to the int variable n.
How can an unsigned variable allow signed values?
unsigned int number=-13;
Why do you think so?
This question is a duplicate.
Why do we use suffix in c variables?
These suffixes are not in the variables. They are in constants. We use suffixes, sometimes, to control the types of the constants.
long int n = 12;
In this, 12 is a constant of type int. Small decimal numerals with no suffix are int by default. A numeral for an integer too big to represent in int will be long int or long long int, or possibly a compiler-specific wider type.
Since n is declared to be long int, the int 12 will be converted to a long int for the initialization. This conversion will not change the value.
long int n = 12l;
Here, 12l is a constant of type long int. Since it is used to initialize a long int, no conversion is necessary.
int n = 12l;
Again, 12l is a long int. However, since it is used to initialize an int, it will be converted to int. Since int can represent the value 12, this conversion will not change the value. If the constant were too large to represent in an int, then the conversion would change the value, in some implementation-defined way.
As to why we use suffixes sometimes, consider 1 << 31. The 1 is an int, and we shift it left 31 bits. In C implementations common today, an int has 32 bits, and it can represent numbers from −231 to +231−1. However, 1 << 31 would produce 231, which overflows this int range. The C standard does not define the behavior when that overflow occurs.
To avoid this, we might write 1u << 31. Then 1u is an unsigned int, which can represent numbers from 0 to +232−1. Then 231 fits in this, and there is no overflow. Alternately, if we know long int is 64 bits in the C implementation we are using, we might use 1l << 31, depending on our needs. 1 << 31 would overflow, but 1l << 31 would not.
The u suffix makes a decimal constant unsigned int, unsigned long int, or unsigned long long int, as necessary to holds its value (or possibly a wider type supported by the compiler).
The l suffix makes a decimal constant at least long int (skipping int), but the constant will still be long long int if its value is too large for long int.
If an integer constant is written using octal (starts with 0) or hexadecimal (starts with 0x), then it both signed and unsigned types are considered until one is found that can represent its value: int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, and then compiler-specific types.
unsigned int number = -13;
Here 13 is an int constant, and the - is the negation operator, so the result is an int with value −13. (Note there are no negative integer constants in C; you make a negative integer by negating an integer constant.)
Since it is used to initialize an unsigned int, it is converted to unsigned int. When C converts an integer to an unsigned integer type of width M (meaning the type uses M bits to represent values), it is “wrapped” modulo 2M. This means 2M is added to or subtracted from the value until the result is representable in the destination type. For −13 and a 32-bit unsigned int, wrapping −13 modulo 232 produces −13 + 4,294,967,296 = 4,294,967,283.
Wrapping modulo 2M produces the same result as if you wrote the starting number in binary (using two’s complement with more than M bits, if the number is negative) and removed all but the last M bits. For example, −13 in 64-bit two’s complement is 11111111111111111111111111111111111111111111111111111111111100112 = FFFFFFFFFFFFFFF316. The last 32 bits are 111111111111111111111111111100112 = FFFFFFF316. In plain binary (not two’s complement), that is 4,294,967,283.

macro constants with and without "u" at the end of a number

What is the difference between Usage
#define CONSTANT_1 (256u)
#define CONSTANT_2 (0XFFFFu)
and
#define CONSTANT_1 (256)
#define CONSTANT_2 (0XFFFF)
when do I really need to add u and what problems we get into if not?
I am more interested in the example expressions where one usage can go wrong with other usage.
The trailing u makes the constant have unsigned type. For the examples given, this is probably unnecessary and may have surprising consequences:
#include <stdio.h>
#define CONSTANT_1 (256u)
int main() {
if (CONSTANT_1 > -1) {
printf("expected this\n");
} else {
printf("but got this instead!\n");
}
return 0;
}
The reason for this surprising result is the comparison is performed using unsigned arithmetics, -1 being implicitly converted to unsigned int with value UINT_MAX. Enabling extra warnings will save the day on modern compilers (-Wall -Werror for gcc and clang).
256u has type unsigned int whereas 256 has type int. The other example is more subtle: 0xFFFFu has type unsigned int, and 0xFFFF has type int except on systems where int has just 16 bits where it has type unsigned int.
Some industry standards such as MISRA-C mandate such constant typing, a counterproductive recommendation in my humble opinion.
The u indicates that the decimal constant is unsigned.
Without that, because the value fits in the range of signed integer, it'll be taken as a signed one.
Quoting C11, chapter 6.4.4.1, Integer constants
The type of an integer constant is the first of the corresponding list in which
its value can be represented.
Suffix Decimal Constant Octal or Hexadecimal Constant
---------------------------------------------------------------------------
none int int
long int unsigned int
long long int long int
unsigned long int
long long int
unsigned long long int
u or U unsigned int unsigned int
unsigned long int unsigned long int
unsigned long long int unsigned long long int

C - convert from string to unsigned int

How do I convert from string to unsigned int?
I know that strtoul() converts from string to unsigned long int, but I want normal int and not long int.
I haven't been able to find a function that does that.
but I want normal [unsigned] int and not long [unsigned] int.
You want to use strtoul(), assign it to a long unsigned int, test the result for being in the range of [0..UINT_MAX] and if this is the case assign the long unsigned int to an unsigned int.
Just tested and found out that strtoul converts to a value equal to UINT_MAX so I guess this works.

Cast implied unsigned integer type?

I'm new to C and have seen code such as (unsigned)b
Does that imply that b will be an unsigned int? Or what type does it imply?
b will be whatever type it was to begin with. That doesn't change
(unsigned)b will evaluate as whatever value b is, but that is subject to the cast to unsigned, which is synonymous with unsigned int.
How that happens depends entirely on the type of b to begin with, whether that type is convertible to unsigned int, and whether the value contained therein falls unscathed between 0...UINT_MAX or not.
Ex:
#include <stdio.h>
void foo(unsigned int x)
{
printf("%u\n", x);
}
int main()
{
int b = 100;
foo((unsigned)b); // will print 100
char c = 'a';
foo((unsigned)c); // will print 97 (assuming ASCII)
short s = -10; // will print 4294967286 for 32-bit int types
// (see below for why)
foo((unsigned)s);
// won't compile, not convertible
//struct X { int val; } x;
//foo((unsigned)x);
}
The only part of this that may raise your eye brow is the third example. When a value of a convertible type to an unsigned type is out of the unsigned type's range (ex: negative values are not same-value representable with any unsigned target types), the value is converted by repeatedly added the maximum value representable by the unsigned target plus-one to the out-of-range value until such time as it falls within the valid range of the unsigned type.
In other words, because -10 is not within the valid representation of unsigned int, UINT_MAX+1 is added to -10 repeatedly (only takes once in this case) until the result is within 0...UINT_MAX.
Hope that helps.
unsigned is a short of unsigned int
signed is a short of signed int
long is the short of long int
long long is the short of long long int
short is the short of short int

Type of constant in "unsigned ux = 2147483648;"

If I write this declaration:
unsigned ux = 2147483648;
(231), will the C compiler treat 2147483648 as an unsigned or signed value?
I've heard that constant values are always treated as signed, but I don't think that's always right.
The value of an unsuffixed decimal constant such as 2147483648 depends on the value of the constant, the ranges of the predefined type, and, in some cases on the version of the C standard you're using.
In C89/C90, the type is the first of:
int
long int
unsigned long int
in which it fits.
In C99 and later, it's the first of:
int
long int
long long int
in which it fits.
You didn't tell us what implementation you're using, but if long int is 32 bits on your system, then 2147483648 will be of type unsigned long int if you have a pre-C99 compiler, or (signed) long long int if you have a C99 or later compiler.
But in your particular case:
unsigned ux = 2147483648;
it doesn't matter. If the constant is of type unsigned int, then it's already of the right type, and no conversion is necessary. If it's of type long long int (as it must be in C99 or later, given 32-bit long), then the value must be converted from that type to unsigned. Conversion from a signed type to an unsigned type is well defined.
So if unsigned is wide enough to represent the value 2147483648, then that's the value that will be stored in ux. And if it isn't (if unsigned int is 16 bits, for example), then the conversion will result in 0 being stored in ux.
You can exercise some control over the type of a constant by appending a suffix to it. For example, 2147483648UL is guaranteed to be of some unsigned type (it could be either unsigned int or unsigned long int).
Incidentally, your question's title is currently "About Class Cast.(if I write unsigned ux=2147483648(2 to the 31 st))", but your question has nothing to do with classes (which don't exist in C) or with casts. I'll edit the question.

Resources