I've run across some code like this:
line += addr & 0x3fULL;
Obviously, 'U' and 'L' are not hex digits. I'm guessing that the 'ULL' at the end of that hex numeric literal means "Unsigned Long Long" - am I correct? (this sort of thing is very difficult to google) if so then this is some sort of suffix modifier on the number?
From the gcc manual:
ISO C99 supports data types for integers that are at least 64 bits wide ( . . . ) . To make an integer constant of type long long int, add the suffix LL to the integer. To make an integer constant of type unsigned long long int, add the suffix ULL to the integer.
These suffixes have also been added to C++ in C++11, and were already supported long long (pun intended) before that as compiler extensions.
Yes that's correct.
0x prefix makes it a hexadecimal literal.
ULL suffix makes it type unsigned long long.
I'm positing a new answer because I recognize that the current answers do not cite from a cross platform source. The c++11 standard dictates that a literal with U/u and LL/ll suffixes is a literal of type: unsigned long long int [source]
U/u is the C/C++ suffix for an unsigned integer.
LL/ll is the C/C++ suffix for a long long integer which is a new type in C++11 and required to have a length of at least 64-bits.
Notes:
The keyword int may be omitted if any modifiers are used, unsigned long long for example. So this will define one as an unsigned long long int, and any number assigned to it will be static_cast to unsigned long long int: unsigned long long one = 1
c++11 marked the advent of auto. Which sets the variable type to the type assigned to it on declaration. For example, because 2ULL is an unsigned long long int literal two will be defined as an unsigned long long int: auto two = 2ULL
c++14 introduced order independent literal suffixes. Previously the U/u suffix had to preceded any size suffix. But circa c++14 the suffixes are accepted in either order, so now since 3LLU is an unsigned long long int literal three will be defined as an unsigned long long int: auto three = 3LLU
Related
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.
I came accross this statement:
time_t time = x / 1000LL;
So what does this LL actually mean?
Copy-pasted from this question, which seems to be the exact same one with the ULL suffix :
From the gcc manual:
ISO C99 supports data types for integers that are at least 64 bits wide, and as an extension GCC supports them in C90 mode and in C++.
Simply write long long int for a signed integer, or unsigned long
long int for an unsigned integer. To make an integer constant of type
long long int, add the suffix LL to the integer. To make an
integer constant of type unsigned long long int, add the suffix
ULL to the integer.
It, indeed, is a suffix for the long long int type.
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.
What does the postfix (or suffix) U mean for the following values?
0U
100U
It stands for unsigned.
When you declare a constant, you can also specify its type. Another common example is L, which stands for long. (and you have to put it twice to specify a 64-bit constant).
Example: 1ULL.
It helps in avoiding explicit casts.
Integer constants in C and C++ can optionally have several suffixes:
123u - the value 123 is an unsigned int
123l - (that's a lowercase L) 123 is a signed long
123L - ditto
123uL - unsigned long
123LL - a signed long long, a 64 bit or 128 bit value (depending on the environment)
123uLL - unsigned long long
You can read more here: https://en.cppreference.com/w/cpp/language/integer_literal
i'm using c++, even if i declare long int, there is error like......
long int num = 600851475143;
warning: integer constant is too large for ‘long’ type
which datatype should be used in this case?
You have to put the suffix L after the number:
long long int num = 600851475143LL;
A lot of it depends on the platform and compiler you are using.
If you are on a x64 platform, a long datatype in C++ should work.
A signed long ranges from −9,223,372,036,854,775,808 to +9,223,372,036,854,775,807. An unsigned long on the other hand ranges from 0 to +18,446,744,073,709,551,615.
Also depending on the compiler and platform there are a few other datatypes which effectively is the same thing (doubleword, longword, long long, quad, quadword, int64).
C (not C++) supports the long long data type. Say if you are on Fedora 10 x32 then gcc 4.3.0 supports the long long datatype but you must put the LL after the large literal. See
http://www.daniweb.com/forums/thread162930-2.html
You should distinguish type of variable from type of integer expression you use as value being assigned to variable. As tur1ng specified, you are supposed to use integer literal suffix to precise type of value you assign if ambiguity may occur.
Unsuffixed decimal value can have different type: int, long int, unsigned long int, long long int, so it's a good idea to be explicit.
you just have to do as follows (if you are using java):
long num = 60085147514L;
this declares it as "long" data type which allows you to store longer numbers