views:

180

answers:

3

Is there efficient way to do this?

+4  A: 

That's something you could be using a union for:

union {
    UINT64 ui64;
    struct {
        DWORD d0;
        DWORD d1;
    } y;
} un;

un.ui64 = 27;
// Use un.y.d0 and un.y.d1

An example (under Linix so using different types):

#include <stdio.h>
union {
    long ui64;
    struct {
        int d0;
        int d1;
    } y;
} un;
int main (void) {
    un.ui64 = 27;
    printf ("%d %d\n", un.y.d0, un.y.d1);
    return 0;
}

This produces:

27 0
paxdiablo
Or just use the built-in ULARGE_INTEGER Union, see http://msdn.microsoft.com/en-us/library/aa383742(VS.85).aspx
eran
Yeah, I know the question stated Win32, but I still prefer my code to be portable (not depending on the platform).
paxdiablo
Pax, your code is not portable either -- mind you, the width of int and long differs among platforms and may even be equal.
Johannes Passing
In Win32, uint64 and dword have specific meanings. The union is portable among compilers that support those Win32 types. The second bit of code was simply meant as an expansion (full program), showing code which could use that method. I used Linux since I didn't have a Windows box available at the time.
paxdiablo
A: 

Keep in mind that 64-bit integers have alignment restrictions at least as great as 32-bit integers on all platforms. Therefore, it's perfectly safe to cast a pointer to a 64-bit integer as a pointer to a 32-bit.

ULONGLONG largeInt;
printf( "%u %u\n", ((DWORD *)&largeInt)[ 0 ], ((DWORD *)&largeInt)[ 1 ] );

Obviously, Pax's solution is a lot cleaner, but this is technically more efficient since it doesn't require any data copying.

Peter Ruderman
+1  A: 

Thought I would provide an example using LARGE_INTEGER FOR the windows platform. If I have a variable called "value" that is 64 bit, then I do:

LARGE_INTEGER li;
li.QuadPart = value;
DWORD low = li.LowPart;
DWORD high = li.HighPart;

Yes, this copies it, but I like the readability of it.

BrianK