Rahul Gupta
asked on
Unsigned int64 to unsigned int32
Fastest and efficient way to convert (unsigned) _uint64 to two (unsigned) _uint32
example
somefunc(in _uint64 , out _uint32, out _uint32)
example
somefunc(in _uint64 , out _uint32, out _uint32)
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Yep. The C implementation is specifically mindful of the underlying hardware requirements and all integer type operations MUST work correctly according to the rules.
Now if you were to store the 64-bit value and try to extract it from the memory address and memory address+4 locations, all bets are off. In this case you'd be at the mercy of the big/little endian rules.
But with integer operations the value is already converted to its "native" value in one of the hardware registers so it's simply a matter of selecting the upper or lower 32 bits.
Kent
Now if you were to store the 64-bit value and try to extract it from the memory address and memory address+4 locations, all bets are off. In this case you'd be at the mercy of the big/little endian rules.
But with integer operations the value is already converted to its "native" value in one of the hardware registers so it's simply a matter of selecting the upper or lower 32 bits.
Kent
ASKER
I had done in this way...
_uint64= _uint64(_uint64(_uint32var1) << 32) | _uint32var2;
_uint32var1 = _uint32(_uint64variable & &HFFFFFFFF);
_uint32var2 = _uint32(_uint64variable >> 32);
That's essentially the same. The only significant different is that on line 3, you mask off the lower 32 bits of the 64 bit value before storing it in a 32-bit container. The mask is unnecessary since the container can't possibly hold more than 32 bits.
Kent
Kent
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
If you need that solution to be mindful of different hardware then you would change the type with conditional compilation and it would be just as fast...
In C/C++ you can get the same effect by having a struct for the two smaller pieces.
struct Two32s {
_uint32 Low;
_uint32 High;
};
union 64BitSplit {
_uint64 Whole;
Two32s Split;
};
I haven't done C/C++ in a long time, so the code is "as is"... just to get the gyst of it. If someone else feels the need to correct, by all means do!
If you assign to a variable of type 64BitSplit as
MyVar.Whole = VALUE;
You can then read out MyValue.Low and MyValue.High. The Union makes the two structures occupy the same memory.
Once again, if the CPU independence is important then you should use conditional defines to make the struct swap low for high as needed.
struct Two32s {
_uint32 Low;
_uint32 High;
};
union 64BitSplit {
_uint64 Whole;
Two32s Split;
};
I haven't done C/C++ in a long time, so the code is "as is"... just to get the gyst of it. If someone else feels the need to correct, by all means do!
If you assign to a variable of type 64BitSplit as
MyVar.Whole = VALUE;
You can then read out MyValue.Low and MyValue.High. The Union makes the two structures occupy the same memory.
Once again, if the CPU independence is important then you should use conditional defines to make the struct swap low for high as needed.
That code will sometimes work, but it's hardware dependent.
It doesn't work for both big and little endian systems. It should also have the appropriate #PRAGMA or command line option to force data alignment to the 32-bit boundary (or less).
Kent
It doesn't work for both big and little endian systems. It should also have the appropriate #PRAGMA or command line option to force data alignment to the 32-bit boundary (or less).
Kent
Since you need to compile for little endian versus big endian, conditional compilation takes care of that... I thought I mentioned that already...
ASKER