The language guarantees that int is at least 16 bits, long is at least 32 bits, and long can represent at least all the values that int can represent.
If you assign a long value to an int object, it will be implicitly converted. There's no need for an explicit cast; it would merely specify the same conversion that's going to happen anyway.
On your system, where int and long happen to have the same size and range, the conversion is trivial; it simply copies the value.
On a system where long is wider than int, if the value won't fit in an int, then the result of the conversion is implementation-defined. (Or, starting in C99, it can raise an implementation-defined signal, but I don't know of any compilers that actually do that.) What typically happens is that the high-order bits are discarded, but you shouldn't depend on that. (The rules are different for unsigned types; the result of converting a signed or unsigned integer to an unsigned type is well defined.)
If you need to safely assign a long value to an int object, you can check that it will fit before doing the assignment:
#include <limits.h> /* for INT_MIN, INT_MAX */
/* ... */
int i;
long li = /* whatever */
if (li >= INT_MIN && li <= INT_MAX) {
i = li;
}
else {
/* do something else? */
}
The details of "something else" are going to depend on what you want to do.
One correction: int and long are always distinct types, even if they happen to have the same size and representation. Arithmetic types are freely convertible, so this often doesn't make any difference, but for example int* and long* are distinct and incompatible types; you can't assign a long* to an int*, or vice versa, without an explicit (and potentially dangerous) cast.
And if you find yourself needing to convert a long value to int, the first thing you should do is reconsider your code's design. Sometimes such conversions are necessary, but more often they're a sign that the int to which you're assigning should have been defined as a long in the first place.
The language guarantees that int is at least 16 bits, long is at least 32 bits, and long can represent at least all the values that int can represent.
If you assign a long value to an int object, it will be implicitly converted. There's no need for an explicit cast; it would merely specify the same conversion that's going to happen anyway.
On your system, where int and long happen to have the same size and range, the conversion is trivial; it simply copies the value.
On a system where long is wider than int, if the value won't fit in an int, then the result of the conversion is implementation-defined. (Or, starting in C99, it can raise an implementation-defined signal, but I don't know of any compilers that actually do that.) What typically happens is that the high-order bits are discarded, but you shouldn't depend on that. (The rules are different for unsigned types; the result of converting a signed or unsigned integer to an unsigned type is well defined.)
If you need to safely assign a long value to an int object, you can check that it will fit before doing the assignment:
#include <limits.h> /* for INT_MIN, INT_MAX */
/* ... */
int i;
long li = /* whatever */
if (li >= INT_MIN && li <= INT_MAX) {
i = li;
}
else {
/* do something else? */
}
The details of "something else" are going to depend on what you want to do.
One correction: int and long are always distinct types, even if they happen to have the same size and representation. Arithmetic types are freely convertible, so this often doesn't make any difference, but for example int* and long* are distinct and incompatible types; you can't assign a long* to an int*, or vice versa, without an explicit (and potentially dangerous) cast.
And if you find yourself needing to convert a long value to int, the first thing you should do is reconsider your code's design. Sometimes such conversions are necessary, but more often they're a sign that the int to which you're assigning should have been defined as a long in the first place.
A long can always represent all values of int.
If the value at hand can be represented by the type of the variable you assign to, then the value is preserved.
If it can't be represented, then for signed destination type the result is formally unspecified, while for unsigned destination type it is specified as the original value modulo 2n, where n is the number of bits in the value representation (which is not necessarily all the bits in the destination).
In practice, on modern machines you get wrapping also for signed types.
That's because modern machines use two's complement form to represent signed integers, without any bits used to denote "invalid value" or such – i.e., all bits used for value representation.
With n bits value representation any integer value is x is mapped to x+K*2n with the integer constant K chosen such that the result is in the range where half of the possible values are negative.
Thus, for example, with 32-bit int the value -7 is represented as bitpattern number -7+232 = 232-7, so that if you display the number that the bitpattern stands for as unsigned integer, you get a pretty large number.
The reason that this is called two's complement is because it makes sense for the binary numeral system, the base two numeral system. For the binary numeral system there's also a ones' (note the placement of the apostrophe) complement. Similarly, for the decimal numberal system there's ten's complement and niners' complement. With 4 digit ten's complement representation you would represent -7 as 10000-7 = 9993. That's all, really.
I'm using a library function which takes arrays of long's as inputs (and single long's too), and modifies these arrays. As long as all the numbers inside the library stay within the int size limit (i.e. there are no calculations that would overflow int), is it 100% safe for me to pass it arrays of int's, or should I manually typecast my arrays using for loops from int to long before input? And then assume that these arrays still contain int's?
What if this was some other integer type, like unsigned int?
I am worried that, for example, number 5 has different bit representation (and is stored using a different number of bits) across these various data types. Will C figure it out and do the correct thing?
Just because they are the same type doesn't mean you can literally exchange the characters in your source code.
The syntax is confused by a T() cast when T has a space in it.
Write c = a * (long int)b instead.
Use brackets for this. eg.
c = a * (long int) (b)
As type casted data type have multi-words.
int is guaranteed to be at least 16 bits wide. On modern systems, it's most commonly 32 bits (even on 64-bit systems).
long long, which didn't originally exist in C++, is guaranteed to be at least 64 bits wide. It's almost always exactly 64 bits wide.
The usual way to convert a value from one integer type to another is simply to assign it. Any necessary conversion will be done implicitly. For example:
int x = 42;
long long y = 9223372036854775807;
y = x; // implicitly converts from int to long long
x = y; // implicitly converts from long long to int
For a narrowing conversion, where the target type can't represent all the values of the source type, there's a risk of overflow; int may or may not be able to hold the value 9223372036854775807. In this case, the result is implementation-defined. The most likely behavior is that the high-order bits are discarded; for example, converting 9223372036854775807 to int might yield 2147483647. (This is clearer in hexadecimal; the values are 0x7fffffffffffffff and 0x7fffffff, respectively.)
If you need to convert explicitly, you can use a cast. A C-style cast uses the type name in parentheses:
(long long)x
Or you can use a C++-style static_cast:
static_cast<long long>(x)
which is somewhat safer than a C-style cast because it's restricted in which types it can operate on.
Type long long is typically 64 bits.
Type int is likely to be 32 bits, but not on all machines.
If you cast an int to a long long, you can do
my_long_long = (long long) my_int
and it will be just fine. If you go the other direction, like
my_int = (int) my_long_long
and the int is smaller than 64-bits, it won't be able to hold all the information, so the result may not be correct.
Here is my code:
long long NUM = GetLongLong(); char a = NUM;