Unsigned keyword in C++ - c++

Does the unsigned keyword default to a specific data type in C++? I am trying to write a function for a class for the prototype:
unsigned Rotate(unsigned object, int count)
But I don't really get what unsigned means. Shouldn't it be like unsigned int or something?

From the link above:
Several of these types can be modified using the keywords signed, unsigned, short, and long. When one of these type modifiers is used by itself, a data type of int is assumed
This means that you can assume the author is using ints.

Integer Types:
short -> signed short
signed short
unsigned short
int -> signed int
signed int
unsigned int
signed -> signed int
unsigned -> unsigned int
long -> signed long
signed long
unsigned long
Be careful of char:
char (is signed or unsigned depending on the implmentation)
signed char
unsigned char

Does the unsigned keyword default to a data type in C++
Yes,signed and unsigned may also be used as standalone type specifiers
The integer data types char, short, long and int can be either signed or unsigned depending on the range of numbers needed to be represented. Signed types can represent both positive and negative values, whereas unsigned types can only represent positive values (and zero).
An unsigned integer containing n bits can have a value between 0 and 2n - 1
(which is 2n different values).
However,signed and unsigned may also be used as standalone type specifiers, meaning the same as signed int and unsigned int respectively. The following two declarations are equivalent:
unsigned NextYear;
unsigned int NextYear;

You can read about the keyword unsigned in the C++ Reference.
There are two different types in this matter, signed and un-signed. The default for integers is signed which means that they can have negative values.
On a 32-bit system an integer is 32 Bit which means it can contain a value of ~4 billion.
And when it is signed, this means you need to split it, leaving -2 billion to +2 billion.
When it is unsigned however the value cannot contain any negative numbers, so for integers this would mean 0 to +4 billion.
There is a bit more informationa bout this on Wikipedia.

Yes, it means unsigned int. It used to be that if you didn't specify a data type in C there were many places where it just assumed int. This was try, for example, of function return types.
This wart has mostly been eradicated, but you are encountering its last vestiges here. IMHO, the code should be fixed to say unsigned int to avoid just the sort of confusion you are experiencing.

Related

Why doesn't unsigned long long int in C++ allow negative values?

I tried using the unsigned long long int type for implementing something similar to the BigInteger of Java in C++ but I found out that unfortunately unsigned long long int doesn't support negative values. Why doesn't C++ allow unsigned long long int to store negative values when it has such a huge range for positive values?
The keyword unsigned is a modifier for integer types and it means that the variable can't represent negative values. With this limitation it will however be able to store greater positive values than its signed counterpart. Which one you should choose depends on the situation.
Example:
A signed 8 bit integer can (since C++20) hold values in the range [-2^7, 2^7-1] ([-128, 127]).
An unsigned 8 bit integer can hold values in the range [0, 2^8-1] ([0, 255]).
Signedness # wikipedia

Why does the base of a literal affect its type?

The decimal number 4294967295 is equal to hexadecimal 0xFFFFFFFF, so I would expect a literal to have the same type regardless of what base it is expressed in, yet
std::is_same<decltype(0xFFFFFFFF), decltype(4294967295)>::value; //evaluates false
It appears that on my compiler decltype(0xFFFFFFFF) is unsigned int, while decltype(4294967295) is signed long.
hex literals and decimal literals types are determined differently from lex.icon table 7
The type of an integer literal is the first of the corresponding list in Table 7 in which its value can be represented.
when there is no suffix for decimal literal the types listed are in order:
integer
long int
long long int
for hexidecimal the list in order are:
int
unsigned int
long int
unsigned long int
long long int
unsigned long long int
Why does this difference exist? Considering we also have this in C, we can look at the C99 rationale document and it says:
Unlike decimal constants, octal and hexadecimal constants too large to be ints are typed as
unsigned int if within range of that type, since it is more likely that they represent bit
patterns or masks, which are generally best treated as unsigned, rather than “real” numbers.

C++ Primer paragraph on Integer literals, need someone to clarify some points

I'm currently working through C++ Primer (5th Edition), and I'm struggling trying to figure out what the author means in this part on literals (Chapter 2, section 2.1.3):
... By default, decimal literals are signed whereas octal and hexadecimal literals can be either signed or unsigned types. A decimal literal has the smallest type of int, long, or long long (i.e., the first type in this list) in which the literal’s value fits. Octal and hexadecimal literals have the smallest type of int, unsigned int, long, unsigned long, long long, or unsigned long long in which the literal’s value fits. It is an error to use a literal that is too large to fit in the largest related type...
In the first sentence, does the author mean that decimal literals are signed according to the C++ standard, and for octal and hexadecimal literals it depends on the compiler?
The next three sentences really confuse me though, so if someone could offer an alternative explaination, it would be greatly appreciated.
If you have an integer literal for example a decimal integer literal the compiler has to define its type. For example a decimal literal can be used in expressions and the compiler need to determine the type of an expression based on the types of its operands.
So for decimal integer literals the compiler selects between the following types
int
long int
long long int
and choices the first type that can accomodate the decimal literal.
It does not consider unsigned integer types as for example unsigned int or unsigned long int though they could accomodate a given literal.
The situation is different when the compiler deals with octal or hexadecimal integer literals. In this case it considers the following types in the given order
int
unsigned int
long int
unsigned long int
long long int
unsigned long long int
That it would be more clear consider an artificial example to demonstrate the idea. Let's assume that you have a value equal to 127. This value can be stored in type signed char. Now what about value 128? It can not be stored in an object of type signed char because the maximum positive value that can be stored in an object of type signed char is 127.
What to do? We could store 128 in an object of type unsigned char because its maximum value is 255. However the compiler prefers to store it in an object of type signed short.
But if this value was specified like 0x80 then the compiler would select an object of type unsigned char
It is of course an imaginary process.
However in realty a similar algorithm is used for decimal literals only the compiler takes into account integer types starting from int that to determine the type of a decimal literal.
Decimal (meaning base-10) literals are those that have no prefix. The author is saying that these are always signed.
5 // signed int (decimal)
12 // signed int (decimal)
They can also be signed or unsigned based on either you providing a suffix. Here's a full reference for integer literal syntax.
5 // signed int
7U // unsigned int
7UL // unsigned long
Hex (base-8) values will be prefixed with 0x.
0x05 // int (hex)
Similarly octal (base-8) values are prefixed with 0.
05 // int (octal)
To append to Cory's answer:
The relevant diagram in the link states
Types allowed for integer literals
No suffix, regular decimal
int, long int, long long int(since C++11)
So the decimal number
78625723
Is represented by a signed type.
No suffix hexadecimal or octal bases
int, long int,
unsigned int, unsigned long int
long long int(since C++11)
unsigned long long int(since C++11)
So the 0x hex number
0x78625723
Might be represented by a signed or an unsigned value.
The place this is relevant is when you have literal values that are just a little too big to fit in a signed type, but do fit in the corresponding unsigned type. For example, on a machine with 16-bit int and 32-bit long (rare these days, but the minimum allowed by the spec), the constant literal 0xffff will be an unsigned int, while the literal 65535 (same value) will be a long.
Of course, you can force the latter to be an unsigned by using a U suffix; this part of the spec is only relevant for literals with no suffix.

The "unsigned" keyword [duplicate]

This question already has answers here:
Difference between unsigned and unsigned int in C
(5 answers)
Closed 9 years ago.
I saw in some C++ code the keyword "unsigned" in the following form:
const int HASH_MASK = unsigned(-1) >> 1;
and later:
unsigned hash = HASH_SEED;
(it is taken from the CS106B/X reader - of Stanford - by Eric S. Roberts - on the topic of "implementation of the hash code function for strings").
Can someone tell me please what does that keyword mean and when do I use it anyway?
Thanks!
Take a look: https://stackoverflow.com/a/7176690/1758762
unsigned is a modifier which can apply to any integral type (char,
short, int, long, etc.) but on its own it is identical to unsigned
int.
It's a short version of unsigned int. Syntactically, you can use it anywhere you would use any other datatype like float or short.
Unsigned types are types that can't represent negative numbers; only zero and positive numbers. In C++, they use modular arithmetic; the modulus for an N-bit type is 2^N. It's a good idea to use unsigned rather than signed types when messing around with bit patterns (for example, when calculating hash codes), since C++ allows several different representations of negative numbers which could lead to portability issues.
unsigned can be used as a qualifier for any integer type (e.g. unsigned int or unsigned long long); or on its own as shorthand for unsigned int.
So the first converts -1 into unsigned int. Due to modular arithmetic, this gives the largest representable value. This could also be written (more clearly, in my opinion) as std::numeric_limits<unsigned>::max().
The second declares and initialises a variable of type unsigned int.
Values are signed by default, which means they can be positive or negative. The unsigned keyword is used to specify that a value must be positive.
Signed variables use 1 bit to specify whether the value is positive or not. The unsigned keyword actualy makes this bit part of the value (thus allowing bigger numbers to be stored).
Lastly, unsigned hash is interpreted by compilers as unsigned int hash (int being the default type in C programming).
To get a good idea what unsigned means, one has to understand signed and unsigned integers. For a full explanation of twos-compliment, search Wikipedia, but in a nutshell, a computer stores negative numbers by subtracting negative numbers from 2^32 (for a 32-bit integer). In this way, -1 is stored as 2^32-1. This does mean that you only have 2^31 positive numbers, but that is by the by. This is known as signed integers (as it can have positive or negative sign)
Unsigned tells the compiler that you don't want twos compliment and are dealing only in positive numbers. When -1 is typecast (as it is in the code) to an unsigned int it becomes
2^32-1 = 0b111111111...
Thus that is an easy way of getting a whole lot of 1s in binary.
Use unsigned rarely. If you need to do bit operations, or for some reason need only positive integers bigger than 2^31. Otherwise, if you leave it out, c++ assumes signed integers.
C allows chars to be signed or unsigned, depending on which is more efficient for the host computer. if you want to be sure your char is unsigned, you can declare your variable to be unsigned char. You can use signed char if you want the ensure signed interpretation.
Incidentally, the C and C++ compilers treatd char, signed char, and unsigned char as three distinct types, even though char is compiled into one of the other two.

Is `int` by default `signed long int` in C++?

Is int by default signed long int in C++?
Is it platform and/or compiler dependent? If so, how?
[EDIT]
Are any of the following guaranteed to be duplicate?
signed short int
signed int
signed long int
signed long long int
unsigned short int
unsigned int
unsigned long int
unsigned long long int
plain int is signed, whether or not it's the same size as long int is platform-dependent.
What's guaranteed is that
sizeof (int) <= sizeof (long)
and int is big enough to hold at least all values from -32767 to 32767.
What the standard says: (section [basic.fundamental]:
There are five standard signed integer types : signed char, short int, int, long int, and long long int. In this list, each type provides at least as much storage as those preceding it in the list. There may also be implementation-defined extended signed integer types. The standard and extended signed integer types are collectively called signed integer types. Plain ints have the natural size suggested by the architecture of the execution environment; the other signed integer types are provided to meet special needs.
All of the integer types are different, i.e. you can safely overload functions for all of them and you won't get any conflict. However, some times use the same number of bits for their representation. Even if they use the same number of bits signed and unsigned types always have a different range. Except for char, using any integer type without signed is equivalent to using it with signed, i.e. signed int and int are equivalent. char is a different type as signed char and unsigned char but char has the same representation and range of either signed char or unsigned char. You can use std::numeric_limits<char>::is_signed to find out which it uses.
On to the more interesting aspects. The following conditions are all true:
7 <= std::numeric_limits<signed char>::digits
sizeof(char) == 1
sizeof(char) == sizeof(signed char)
sizeof(char) == sizeof(unsigned char)
15 <= std::numeric_limits<short>::digits
sizeof(char) <= sizeof(short)
sizeof(short) <= sizeof(int)
31 <= std::numeric_limits<long>::digits
sizeof(int) <= sizeof(long)
63 <= std::numeric_limits<long long>::digits
sizeof(long) <= sizeof(long long)
sizeof(X) == sizeof(signed X)
sizeof(signed X) == sizeof(unsigned X)
(where "X" is one of char, short, int, long, and long long).
This means that the size of all integer types can be the same as long as this types hold at least 64 bits (and apparently the Cray X-MP was such a beast). On contemporary machines typically sizeof(int) == sizeof(long) but there are machines where sizeof(int) == sizeof(short). Whether long is 32 or 64 bits depends on the actual architecture and both kinds are currently around.
Plain int is equivalent to signed int. That much is standard. Anything past that is not guaranteed; int and long are different types, even if your particular compiler makes them the same size. The only guarantee you have is that a long is at least as big as an int.
The long and short modifiers are not exactly like signed and unsigned. The latter two can be put on any integer type, but if you leave them off, then signed is the default for each integer type (except char). So int and signed int are the same type.
For long and short, if you leave them off, neither is chosen, but the resulting type is different. long int, short int and int are all different types, with short int <= int <= long int.
The int after long, short, signed and unsigned is optional: signed int and signed are the same type.
In C++ int is signed int by default, so there is no problem with that. However, int and long int are different types in C++, so this is not the same from the point of view of the language. Implementation of int and long int is platform/compiler specific - they are both integral types which might be identical. The only limitation C++ standard imposes is that sizeof( long int ) >= sizeof( int ).
signed and int are both the same as signed int by default.
Neither is the same type as signed short int or signed long int.