2 Questions
First, while
long long int num = 1000000000000;
works fine
long long int num = 4014109449;
gives
warning: this decimal constant is unsigned only in ISO C90 [enabled by default]
What does it mean ?
Secondly
long long int num = 1000000*1000000;
gives an overflow warning
while
long long int num = 1000000000000;
is ok,even though they are same.How do i get rid of it? Multiplication gives a garbage value
The problem is that the value 4014109449 is an unsigned long int in C90 but a long long int in C99 because it is too large for a 32-bit long int. While 1000000000000 is too large for any 32-bit type, so is automatically a long long int. The warning relates to the fact that the behaviour differs between C90 and C99.
The solution is to force type agreement between the literal and the variable type by using an appropriate type suffix. In this case:
long long num = 4014109449LL ;
or use a type cast:
long long num = (long long)4014109449 ;
Similarly the expression 1000000 * 1000000 is a multiply of two int types and has an int result, but causes an overflow - there is no automatic promotion to a larger type for int expressions. The solution is again to be explicit about the type of the literal:
long long num = 1000000LL * 1000000LL;
or you can also use a type cast on one or both operands.
long long num = (long long)1000000 * 1000000;
In C90, the type of an unsuffixed decimal integer constant (literal) is the first of
int
long int
unsigned long int
that can represent its value without overflow.
In C99 and later, it's the first of
int
long int
long long int
that can represent its value.
The value 4014109449 happens to be representable as a 32-bit unsigned integer, but not as a 32-bit signed integer. Assuming your system has 32-bit longs, that constant's type is unsigned long int in C90, long long int in C99 and C11.
That's what the warning is telling you. The type of the constant changes depending on which version of the C standard your compiler conforms to.
Note that, regardless of its type, the value of 4014109449 will always be correct, and in your declaration:
long long int num = 1000000000000;
that value will always be correctly converted to long long. But it certainly wouldn't hurt (and would silence the warning) to add a LL suffix to make it explicit that you want a value of type long long:
long long int num = 1000000000000LL;
As for this:
long long int num = 1000000*1000000;
assuming you have 32-bit ints, the constant 1000000 is of type int, and the result of multiplying two int values is also of type int. In this case, the multiplication will overflow. Again, you can avoid the problem by ensuring that the constants are of type long long int:
long long int num = 1000000LL * 1000000LL;
(Note that you can use lowercase ll, but it's a bad idea, since it can be difficult to distinguish the letter l from the digit 1.)
Related
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
long int k=(long int)(2000*2000*2000);
the above calculation is giving me wrong answer in C. What is wrong?
If a C integer constant fits in an int, it is of type int. So your expression is evaluated as:
long int k = (long int)((int)2000*(int)2000*(int)2000);
If int isn't large enough to hold the result of the multiplication, you'll get a signed integer overflow and undefined behavior. So if long is large enough to hold the result, you should write:
long k = 2000L * 2000L * 2000L;
The L suffix forces the type of the literal to long (long is equivalent to long int).
But on most platforms, even long is only a 32-bit type, so you have to use long long which is guaranteed to have at least 64 bits:
long long k = 2000LL * 2000LL * 2000LL;
The LL suffix forces the type of the literal to long long.
2000 is of type int, so 2000*2000*2000 is also of type int.
Assuming a 32-bit int (which is actually more than the standard requires, since an int is not required by the standard to represent a value more than 32767) the maximum representable value is about 2,147,483,647 (commas inserted for readability) which is less than 8,000,000,000.
You will probably want to do the calcuation as 2000LL*2000*2000 which takes advantage of multiplication being left-right associative, and will promote all the 2000 values to long long int before doing the multiplication. Your variable will also need to be of type long long int if you want a guarantee of being able to store the result.
Holt's answer is the correct one, I am just leaving this here as caveat!
You could try to use:
long long int
instead of
long int
However, in my local machine, it has no effect:
#include <stdio.h>
int main(void)
{
long int k=(long int)(2000*2000*2000);
printf("With long int, I am getting: %ld\n", k);
long long int n = 2000*2000*2000;
printf("With long long int, I am getting: %lld\n", n);
return 0;
}
Output:
With long int, I am getting: -589934592
With long long int, I am getting: -589934592
Warnings:
../main.c:6:36: warning: integer overflow in expression [-Woverflow]
long int k=(long int)(2000*2000*2000);
^
../main.c:9:32: warning: integer overflow in expression [-Woverflow]
long long int n = 2000*2000*2000;
Even this:
unsigned long long int n = 2000*2000*2000;
printf("With long long int, I am getting: %llu\n", n);
will overflow too.
There are two problems in your code:
long int is (on most architecture) not enough to store 8e9.
When you do 2000 * 2000 * 2000, operations are made using "simple" int, thus, int * int * int = int so you cast the result to an int and then to a long int.
You need to use long long int and specify that you want long long int:
long long int k = 2000LL*2000LL*2000LL;
Notice the extra LL after 2000 saying "It's 2000, but as a long long int!".
You can't just multiply the values together as ordinary precision integers and then cast the result to a higher precision, because the result has already overflowed at that point. Instead, the operands need to be higher precision integers before they're multiplied. Try the following:
#include <stdio.h>
int main(void)
{
long long int n = (long long int)2000*(long long int)2000*(long long int)2000;
printf("long long int operands: %lld\n", n);
return 0;
}
On my machine, this gives:
long long int operands: 8000000000
What is the difference between
long int numberOfPoints = 131071100; and
long int numberOfPoints = 131071100L;
and is an assignment such as
int numberOfPoints = 131071100L;
legal? And if it is what is the difference between that and the previous two?
The type of an unsuffixed integer constant like 131071100 is the first of int, long int, and long long int in which its value can be represented. The value of 131071100 is always mathematically correct; only its type varies (and since long int is at least 32 bits, it's always either an int or a long int).
With the L suffix, it's of type long int or long long int; again, the value is always correct -- and it happens that 131071100L is always of type long int.
It's perfectly valid to initialize an object of some arithmetic type with an expression of a different numeric type. The value is implicitly converted to the target type. And in this case, since the target type is long int, there is no risk of overflow.
For your particular case, the only difference between
long int numberOfPoints = 131071100;
and
long int numberOfPoints = 131071100L;
is that the latter is slightly more explicit; the meaning is exactly the same.
The L suffix is still needed if the expression is more complicated than a single constant. For example, if you write:
long int foo = 1024 * 1024 * 1024;
then each constant 1024 is of type int -- and so is the entire expression. If int happens to be just 16 bits, then the multiplication will overflow, even though the mathematical result would fit in a long int. (The type of a literal is adjusted depending on its value; the type of a large expression is not.) To avoid that problem, you can write:
long int foo = 1024L * 1024L * 1024L;
(A previous answer here was incorrect and has been amended.)
Per the ANSI C specification (similar language exists in C99 and C++ specifications):
The type of an integer constant is the first of the corresponding list
in which its value can be represented.
Unsuffixed decimal: int, long
int, unsigned long int.
Unsuffixed octal or hexadecimal: int, unsigned
int, long int, unsigned long int.
Suffixed by the letter u or U: unsigned int, unsigned long int.
Suffixed by the letter l or L: long
int, unsigned long int.
Suffixed by both the letters u or U and l or L: unsigned long int.
Therefore, there will not be any difference between the two expressions, since C guarantees that the constant's type will be long enough to hold the value.
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.
Greetings!
I was experimenting with C language till I encountered something very strange.
I was not able to explain myself the result shown below.
The Code:
#include <stdio.h>
int main(void)
{
int num = 4294967295U;
printf("%u\n", num);
return 0;
}
The Question:
1.) As you see, I created an int which can hold numbers between -2147483648 to 2147483647.
2.) When I assign the value 4294967295 to this variable, the IDE shows me a warning message during compilation because the variable overflowed.
3.) Due to curiosity I added a U (unsigned) behind the number and when I recompiled it, the compiler did not return any warning message.
4.) I did further experiments by changing the U (unsigned) to L (long) and LL (long long). As expected, the warning message still persist for these two but not after I change it to UL (unsigned Long) and ULL (unsigned long long).
5.) Why is this happening?
The Warning Message :(For steps 2)
warning #2073: Overflow in converting constant expression from 'long long int' to 'int'.
The Warning Message:(For steps 4 LL & L)
warning #2073: Overflow in converting constant expression from 'long long int' to 'long int'.
And last, thanks for reading my question, your teachings and advices are much appreciated.
As per the ISO C99 standard, section 6.4.4.1 (Integer Constants), subsection Semantics, the type of an integer constant is the first type of the following table where the value can be represented:
Octal or Hexadecimal
Suffix Decimal Constant 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
l or L long int long int
long long int unsigned long int
long long int
unsigned long long int
both u or U unsigned long int unsigned long int
and l or L unsigned long long int unsigned long long int
ll or LL long long int long long int
unsigned long long int
both u or U unsigned long long int unsigned long long int
and ll or LL
Particular implementations can have extended integer types that follow the same pattern as above.
Perhaps, by default, the compiler assumes you're typing in signed integers. When you give it 4294967295, that number doesn't fit into a 4-byte integer, so it uses an 8-byte integer to store it, instead. Then it has to do a lossy conversion (long long, AKA 8-byte, to long, AKA 4-byte), so it gives you a warning.
However, when you type 4294967295U, it knows you want an unsigned integer. That number fits into a 4-byte unsigned integer, so it has type long int, and no lossy conversion is necessary. (You're not losing data by going from unsigned long int to long int, just mis-representing it.)