I have 2 cores, one is 32 bit and other is 64 bit.
On 64 bit machine, I have support for unsigned long long, and I need to assign this value to a varriable which will be access in 32 bit machine, such as:-
typedef struct {
unsigned int low;
unsigned int high;
} myint64_t;
myint64_t app_sc;
Below is the code snippet for 64 bit machine:
unsigned long long sc;
/* Calculate sc */
...
Now on 64 bit machine, I need to assign "sc" to app_sc, and use it for some computing on 64 bit machine.
I was trying to do something like this:-
app_sc = sc;
but compiler gives me compile time errors. I can similarly do, something like this:-
app_sc.low = sc & 0xFFFFFFFF;
app_sc.high = (sc>>32) & (0xFFFFFFFF);
But does that guarantee, it will work in all cases?
Is there any better way of doing it?
Firstly, I agree with the suggestion of using the
stdint
types if possible, so I'll do so myself.Secondly, the only possibly cheaper way I can think of to do the conversion is via a union, like
Caveats
app_sc
into an instance of this union (skipping the 32-bit loads), then it might be worthwhilesc
is already genuinely stored somewhere in memory, and you can just cast its address to(union Int64 *)
sc
is currently allocated a register and is dirty, taking the address might force a store anywayFrankly it's fragile, as I hope the caveats show. Still, it's another way of doing it, and you can decide whether it's also better in your case.
You can use header file stdint.h for using signed/unsigned variable uint64_t/int64_t/...uint8_t/int8_t for better explanation : http://pubs.opengroup.org/onlinepubs/007904975/basedefs/stdint.h.html
By 32 and 64 bit architecture the thing which change is the size of pointer so unsigned long long will work in the same way in 32 as it worked in 64 bit.
With a not too old compiler supporting a reasonably recent C standard (probably C99, perhaps even earlier) you should have a
<stdint.h>
header giving you a type likeint64_t
(for a signed 64 bits integer) oruint64_t
(for an unsigned 64 bits integer) which is exactly 64 bits, even on 32 bits machine.If your compiler don't have it, I strongly suggest to upgrade your compiler. You could probably use GCC (except if you have a very strange target architecture, unsupported by GCC). Latest GCC version is 4.7.
Notice that 64 bits arithmetic on 32 bits machines needs in practice some compiler support to be reasonably efficient. (e.g. to use add with carry instructions). It can't be done only thru a library, even if a library is required to supply the most complex operations (e.g. 64 bits divisions on 32 bits machines). In other words, fast 64 bits arithmetic can't be portably coded in C for a 32 bits machine.
For much bigger numbers, consider using arbitrary precision numbers (called bigints), e.g. thru the GNU gmp library. Such libraries uses non-trivial algorithms (so even the math is quite difficult, you can read entire books on them and earn a PhD by inventing a competitive bigint implementation).
Your compiler, even on the 32 bit machine, may support "long long int". Try it?