There’s no magic/easy way to do this as far as I know. The alternative would be to use a packed record containing a variant part (multiple variables overlaid on the same data - use one value of the variant part as UInt64, the other as 2 x DWORD). Just stick with your code I think.
Yeah the ‘rearragement’ is due to the value being stored in memory in little endian format:
Value: 0x0123456789ABCDEF
Bits: ^high low^
Memory address: 0 1 2 3 4 5 6 7
Byte value: EF CD AB 89 67 45 23 01
When we use the above value we are working with variables/registers with bits represented highest to lowest, the same as the way that the value is written which is intuitive. Doing shr 32 (shift right) moves the 01234567 part in the high bits down to the low bits (and zeroes the high bits) and the final value is 0x0000000001234567.
But when the value, represented as say UInt64, is stored in memory, the byte order is reversed as EFCD… This little endian format is used with most modern CPUs and applies to all integral types, not just UInt64. So when you overlay 2 x DWORD on that memory the first DWORD (4 bytes) is the low 4 bytes/32 bits of the value and second DWORD is the high 4 bytes/32 bits of the value, resulting in the unexpected results.
Just a nitpick on terms because I saw some people mention “rotate” - shr or shl is not rotate, it is shift. There are also rotate instructions in asm but unfortunately we don’t have them in the pascal language.
Yeah, knew that. Didn’t want to confuse things given the original said rotate . It is odd that we don’t have rotate equivalents. Other than ASM it can be done with two shifts and an or but still odd it’s not there.
The problem for us learners is to realize the flexibility of using Delphi
I never knew an array is also a packed record
But the reality is
const
u : UInt64 = $FEDC_BA98_1234_5678
begin
Lower := U and $FFFF_FFFF;
Upper := U and not $FFFF_FFFF;
Upper := Upper div $FFFF_FFFF;
So why have a record or anything
and UInt64 is a stupid name to use where NNo64 makes sense as natural number is what it is and we do not need to follow ‘C’ with special complicated terms to remember
Cardinal is a long way from a natural number that original Delphi used wrongly
Unsigned & Integer & bitwidth are correct terms but are wordy to be writing all the time
many languages Integer is Integer is targeted at 32 bit and the new languages
use Int to not be wordy
And Delphi has always used Int64 that is Bitwidth
As languages drive to not be wordy they default with Var already set after the procedure statement or header statement - so you don’t have to write it.
Do a structured modern approach to Delphi 1/ simplify 2/ non wordy, 3/ still backward compatible is not stupid thinking at all.
Like Properties Private, Protected, Public, Published is a good example of simplify
I often start my page to include
Type
NNo64: …
NNo32: …
NNo16: Word;
Int32: integer;
just to simplify so I’m reterming things
‘Natural number’ is Mathematics more than Computer Science.
BTW, ‘Natural number’ is equal in the field of mathematics on a level with ‘FreeAndNil’ as to whether it includes zero (ie 0,1,2 3,…) or not (ie 1,2 3,…)
At the end it is opinion
Their is so many things to like about Delphi as every one can pick improvements
Is objects within objects and the main object can do