64 bit variable is stored as 32-bit - c

I have some issue when compiling in ARM cross compiler with a variable of type unsigned long long
The variable represents partition size (~256GBytes). I expect it to be stored as 64-bit, but on printing it using %lld, or even trying to print it as Mega bytes (value/(1024*1024*1024)), I always see the only 32-bit of the real value.
Does anyone know why the compiler store it as 32-bits?
Edit:
My mistake, the value is set in C using the following calculation:
partition_size = st.f_bsize*st.f_frsize;
struct statvfs { unsigned long int f_bsize; unsigned long int f_frsize; ...}
The issue is that f_bsize and f_frsize are only 32 bits, and the compiler does not automatically cast them to 64bits! Casting solved this issue for me.

My mistake........
the value is set in C using the following calcualtion:
partition_size = st.f_bsize*st.f_frsize;
struct statvfs
{ unsigned long int f_bsize; unsigned long int f_frsize;...}
The issue is that f_bsize & f_frsize are only 32 bits, and the compiler does not automatically cast them to 64bits!
Casting solved this issue for me.

The below code prints the whole 64 bits.Try printing it using %llu
main()
{
unsigned long long num = 4611111275421987987;
printf("%llu\n",num);
}

Related

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

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.

I am trying to store value in long long int type but giving wrong return

I am trying to store "10000000000000000000"(19 zeros) inside long long int data type.
#if __WORDSIZE == 64
typedef long long int intmaximum_t;
#else
__extension__
typedef unsigned long int intmaximum_t;
#endif
const intmaximum_t = 10000000000000000000;
But it is giving output "-8446744073709551616" (in negative).
I have 64 bit machine with ubuntu OS. How to store this value?
The largest possible value for a 64 bit long long int is 9,223,372,036,854,775,807. Your number is bigger than that. (Note that this number less the one you get is one off the number you actually want - that's not a coincidence but a property of 2's complement arithmetic).
It would fit in an unsigned long long int, but if you need an unsigned type you'll need to use a large number library for your number, or int128_t if your compiler supports it.
The value 10000000000000000000 is too large to fit in a signed 64-bit integer but will fit in an unsigned 64-bit integer. So when you attempt to assign the value it gets converted in an implementation defined way (typically by just assigning the binary representation directly), and it prints as negative because you are most likely using %d or %ld as your format specifier.
You need to declare your variable as unsigned long long and print it with the %llu format specifier.
unsigned long long x = 10000000000000000000;
printf("x=%llun", x);

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.

Is it safe to compare an (uint32_t) with an hard-coded value?

I need to do bitewise operations on 32bit integers (that indeed represent chars, but whatever).
Is the following kind of code safe?
uint32_t input;
input = ...;
if(input & 0x03000000) {
output = 0x40000000;
output |= (input & 0xFC000000) >> 2;
I mean, in the "if" statement, I am doing a bitwise operation on, on the left side, a uint32_t, and on the right side... I don't know!
So do you know the type and size (by that I mean on how much bytes is it stored) of hard-coded "0x03000000" ?
Is it possible that some systems consider 0x03000000 as an int and hence code it only on 2 bytes, which would be catastrophic?
Is the following kind of code safe?
Yes, it is.
So do you know the type and size (by that I mean on how much bytes is it stored) of hard-coded "0x03000000" ?
0x03000000 is int on a system with 32-bit int and long on a system with 16-bit int.
(As uint32_t is present here I assume two's complement and CHAR_BIT of 8. Also I don't know any system with 16-bit int and 64-bit long.)
Is it possible that some systems consider 0x03000000 as an int and hence code it only on 2 bytes, which would be catastrophic?
See above on a 16-bit int system, 0x03000000 is a long and is 32-bit. An hexadecimal constant in C is the first type in which it can be represented:
int, unsigned int, long, unsigned long, long long, unsigned long long

Displaying very large number

As we know that 4294967295 is the largest number in unsigned int if I multiply this number by itself then how to display it? I have tried:
long unsigned int NUMBER = 4294967295 * 4294967295;
but still getting 1 as answer.
You are getting an overflow. Consider the muplication in hexadecimal:
0xffffffff * 0xffffffff == 0xfffffffe00000001
^^^^^^^^
only the last 32 bits are returned
The solution is to use a larger type such as long long unsigned:
long long unsigned int NUMBER = 4294967295ULL * 4294967295ULL;
The suffix ULL means unsigned long long.
See it working online: ideone
The multiplication overflows.
#include <stdio.h>
int main()
{
unsigned int a = 4294967295;
unsigned int b = 4294967295;
// force to perform multiplication based on larger type than unsigned int
unsigned long long NUMBER = (unsigned long long)a * b;
printf("%llu\n", NUMBER);
}
You state in your question that you know max int is equal to 4294967295. That means that you can't store a number larger than that if you are using unsigned int.
C longs store up to 18,446,744,073,709,551,615 when unsigned on a 64 bit unix system [source] so you need only suffix your numbers with UL : 4294967295UL
If you aren't using a 64-bit unix system then you should use long long unsigned int and suffix with LL
Yes, it's an overflow. If you are using c, there isn't any easy way to do such big number multiply as i knew. Maybe you need write one by yourself. In fact some language support such features originally.

Resources