What is the difference between long int and long long int? [duplicate] - c

What's the difference between long long and long? And they both don't work with 12 digit numbers (600851475143), am I forgetting something?
#include <iostream>
using namespace std;
int main(){
long long a = 600851475143;
}

Going by the standard, all that's guaranteed is:
int must be at least 16 bits
long must be at least 32 bits
long long must be at least 64 bits
On major 32-bit platforms:
int is 32 bits
long is 32 bits as well
long long is 64 bits
On major 64-bit platforms:
int is 32 bits
long is either 32 or 64 bits
long long is 64 bits as well
If you need a specific integer size for a particular application, rather than trusting the compiler to pick the size you want, #include <stdint.h> (or <cstdint>) so you can use these types:
int8_t and uint8_t
int16_t and uint16_t
int32_t and uint32_t
int64_t and uint64_t
You may also be interested in #include <stddef.h> (or <cstddef>):
size_t
ptrdiff_t

long long does not exist in C++98/C++03, but does exist in C99 and c++0x.
long is guaranteed at least 32 bits.
long long is guaranteed at least 64 bits.

To elaborate on #ildjarn's comment:
And they both don't work with 12 digit numbers (600851475143), am I forgetting something?
The compiler looks at the literal value 600851475143 without considering the variable that you're assigning it to/initializing it with. You've written it as an int typed literal, and it won't fit in an int.
Use 600851475143LL to get a long long typed literal.

Your C++ compiler supports long long, that is guaranteed to be at least 64-bits in the C99 standard (that's a C standard, not a C++ standard). See Visual C++ header file to get the ranges on your system.
Recommendation
For new programs, it is recommended that one use only bool, char, int, and double, until circumstance arises that one of the other types is needed.
http://www.somacon.com/p111.php

Depends on your compiler.long long is 64 bits and should handle 12 digits.Looks like in your case it is just considering it long and hence not handling 12 digits.

Related

Size of int, short, long, long long?

According to C99 §5.2.4.2.1-1 the following types have size which is implementation dependant. What is said is they are equal or greater in magnitude than these values:
short >= 8 bits
int >= 16 bits
long >= 32 bits
long long >= 64 bits
I have always heard that long is always 32-bits, and that it is strictly equivalent to int32_t which looks wrong.
What is true?
On my computer long is 64 bits in Linux.
Windows is the only major platform that uses the 32-bit longs in 64-bit mode, exactly because of the false assumptions being widespread in the existing code. This made it difficult to change the size of long on Windows, hence on 64-bit x86 processors longs are still 32 bits in Windows to keep all sorts of existing code and definitions compatible.
The standard is by definition correct, and the way you interpret it is correct. The sizes of some types may vary. The standard only states the minimum width of these types. Usually (but not necessarily) the type int has the same width as the target processor.
This goes back to the old days where performance was a very important aspect. Se whenever you used an int the compiler could choose the fastest type that still holds at least 16 bits.
Of course, this approach is not very good today. It's just something we have to live with. And yes, it can break code. So if you want to write fully portable code, use the types defined in stdint.h like int32_t and such instead. Or to the very least, never use int if you expect the variable to hold a number not in the range [−32,767; 32,767].
I have always heard that long is always 32-bits and it is strictly equivalent to int32_t which looks wrong.
I'm curious where you heard that. It's absolutely wrong.
There are plenty of systems (mostly either 16-bit or 32-bit systems or 64-bit Windows, I think) where long is 32 bits, but there are also plenty of systems where long is 64 bits.
(And even if long is 32 bits, it may not be the same type as int32_t. For example, if int and long are both 32 bits, they're still distinct types, and int32_t is probably defined as one or the other.)
$ cat c.c
#include <stdio.h>
#include <limits.h>
int main(void) {
printf("long is %zu bits\n", sizeof (long) * CHAR_BIT);
}
$ gcc -m32 c.c -o c && ./c
long is 32 bits
$ gcc -m64 c.c -o c && ./c
long is 64 bits
$
The requirements for the sizes of the integer types are almost as you stated in your question (you had the wrong size for short). The standard actually states its requirements in terms of ranges, not sizes, but that along with the requirement for a binary representation implies minimal sizes in bits. The requirements are:
char, unsigned char, signed char : 8 bits
short, unsigned short: 16 bits
int, unsigned int: 16 bits
long, unsigned long: 32 bits
long long, unsigned long long: 64 bits
Each signed type has a range that includes the range of the previous type in the list. There are no upper bounds.
It's common for int and long to be 32 and 64 bits, respectively, particularly on non-Windows 64-bit systems. (POSIX requires int to be at least 32 bits.) long long is exactly 64 bits on every system I've seen, though it can be wider.
Note that the Standard doesn't specify sizes for types like int, short, long, etc., but rather a minimum range of values that those types must be able to represent.
For example, an int must be able to represent at least the range [-32767..32767]1, meaning it must be at least 16 bits wide. It may be wider for two reasons:
The platform offers more value bits to store a wider range (e.g., x86 uses 32 bits to store integer values and 64 bits for long integers);
The platform uses padding bits that store something other than part of the value.
As an example of the latter, supposed you have a 9-bit platform with 18-bit words. In the case of the 18-bit word, two of the bits are padding bits and are not used to store part of the value - the type can still only store [-32767..32767], even though it's wider than 16 bits.
The <stdint.h> header does define integer types with specific, fixed sizes (16-bit, 32-bit), but they may not be available everywhere.
C does not mandate 2's complement representation for signed integers, which is why the range doesn't go from [-32768..32767].

why we require uint64_t when unsigned long is available ? [duplicate]

This question already has answers here:
Reasons to use (or not) stdint
(4 answers)
Closed 8 years ago.
I just wanted to know, Why we need to have uint64_t which is actually a typedef of unsigned long , when unsigned long is anyway available. Is it only for make the name short or any other reason ?
The reason should be pretty obvious; it's a guarantee that there is 64 bits of precision. There is no such guarantee for unsigned long.
The fact that on your system it's a typedef, just means that on your system unsigned long is 64 bits. That's not true in general, but the typedef can be varied (by the compiler implementors) to make the guarantee for uint64_t.
It's not always a typedef for unsigned long, because unsigned long is not universally 64 bit wide. For example, on x64 Windows, unsigned long is 32 bit, only unsigned long long is 64 bit.
Because uint64_t means a type of exactly 64 bits, where unsigned long can be 32 bits or higher.
On a system where unsigned long is 32 bits, it would be used to typedef uint32_t , and unsigned long long would be used to typedef uint64_t.
Yes, it does make it shorter, but that's not the only reason to use it. The main motto of using this typedef-ed data types is to make a code more robust and portable accross various platforms.
Sometimes, unsigned long may not be 64 bits, but a definition of uint64_t will always gurantee 64 bit precision. The typedef of uint64_t can [ read as : will] be varied accross different platform to have a precision of 64 bits.
Example:
for systems having long as 32 bits, uint64_t will be typedef to unsigned long long
for systems having long as 64 bits, uint64_t will be typedef to unsigned long
Not only to make it shorter, but also to make it more descriptive.
If you see in code uint64_t it will be easy to read as unsigned int of 64 bits data type.

Which variable type can hold numbers as big as 10^18

On my computer,
int : 4 byte
long int : 4 byte
long long int : 8 byte
long double : 12 byte
unsigned long double : 12 byte
float : 4 byte
Which variable type should I use to keep numbers as big as 10^18?
For a precise representation, you can use long long. It holds at most 2^63-1 on your box, which is >10^18.
Any of the float types would also work, but the representation will be approximate.
Or if you want to do arithmatic without limitations use GMP
To hold 10^18 as an integer, you need an integer type that's 64 bits wide. It's because int, long int, et. al. vary in size across platforms that certain libraries provide types guaranteed to be of a certain size. For example, in the gnu C library:
#include <stdint.h>
uint64_t myint;
or in the glib library from gnome: http://developer.gnome.org/glib/
#include <glib.h>
guint64 myint;

64 bit operations

I'm writing code for a primality testing function that handles long long int's.Do I have to use special operators for such large numbers?Is there any documentation concerning large number manipulation in C?I'm using the gnu standard library.Thanks.
No, you don't need to do anything special. You handle a long long int just the same way as you would handle a int. Just beware of overflows, as with every native integer type.
If long long ints are supported by your compiler you don't have to do any 'special' kind of stuff. If your processor doesn't support 64-bit types (probably 32-bit-processor then) the compiler will emulate that feature by using sequences of assembly code that breaks up the 64-bit operations into 32-bit ones.
long long is new in C99, though many compilers have supported that as an extension before that.
With gcc a long long is 64 bits, you can use it like any other integer type, nothing special is required.
There's a couple of things to be aware of though, integer constants in the source code needs the LL suffix (or LLU if it's unsigned, e.g. you have to do
long long foo = 123412341234123LL;
and not
long long foo = 123412341234123;
Similarly, for outputting a long long with the printf family, you have to use the conversion specifier "%lld" instead of "%d" or "%ld" (or "%llu" if it's unsigned), e.g.
printf("foo = %lld",foo);
There's some docs about long long in gcc here
If the compiler supports long long int, it works with standard operators.
By the way, long long int is 128 bits on 64-bit unices (where long alone is 64 bits). Use int64_t from <stdint.h> if you need 64-bits on all platforms. This does not apply to 64-bit windows, where long is still 32 bits and long long is 64 bits.
If you are just handling long long int you don't need anything special as long as your compiler supports it. Take care of overflows while adding and multiplying two long long ints
For handling very large numbers(range much greater than that of long long int) have a look at GNU MP BigNum Library
Have a look at the GMP library: http://gmplib.org/

Define the 64 bit width integer in Linux

I try to define a 64 bits width integer using C language on Ubnutu 9.10. 9223372036854775808 is 2^23
long long max=9223372036854775808
long max=9223372036854775808
When I compile it, the compiler gave the warning message:
binary.c:79:19: warning: integer constant is so large that it is unsigned
binary.c: In function ‘bitReversal’:
binary.c:79: warning: this decimal constant is unsigned only in ISO C90
binary.c:79: warning: integer constant is too large for ‘long’ type
Is the long type 64 bits width?
Best Regards,
long long max=9223372036854775808LL; // Note the LL
// long max=9223372036854775808L; // Note the L
A long long type is at least 64 bit, a long type is at least 32 bit. Actual width depends on the compiler and targeting platform.
Use int64_t and int32_t to ensure the 64-/32-bit integer can fit into the variable.
The problem you are having is that the number you're using (9223372036854775808) is 2**63, and the maximum value that your long long can hold (as a 64 bit signed 2s complement type) is one less than that - 2**63 - 1, or 9223372036854775807 (that's 63 binary 1s in a row).
Constants that are too large for long long (as in this case) are given type unsigned long long, which is why you get the warning integer constant is so large that it is unsigned.
The long type is at least 32 bits, and the long long type at least 64 bits (both including the sign bit).
I'm not sure it's will fix your problem (The LL solution looks good). But here is a recomandation :
You should use hexadecimal notation to write the maximal value of something.
unsigned char max = 0xFF;
unsigned short max = 0xFFFF;
uint32_t max = 0xFFFFFFFF;
uint64_t max = 0xFFFFFFFFFFFFFFFF;
As you can see it's readable.
To display the value :
printf("%lld\n", value_of_64b_int);
I think it depends on what platform you use. If you need to know exactly what kind of integer type you use you should use types from Stdint.h if you have this include file on you system.

Resources