Robert Wiltshire
2009-04-03 05:28:10 UTC
Sometimes we use api calls and windows fills in 4 bytes.
If we try to treat these 4 bytes as a longint,
issues can sometimes arise due to difference in
the way unsigned vs signed numbers are handled.
Lets say we end up having a longint, called liNum
If paradox reports that liNum < 0,
then the unsigned longint exceeds our singed longint max,
and therein lies the primary issue.
The goal is simply to calculate the proper result,
and place it into a variable called nResult
; move contents from allocated memory to liNum
RtlMoveMemoryInVar(liNum,liMemoryAddress,4)
if liNum >= 0
then
nResult = number(liNum)
else
nResult = number(liNum) + 4294967296.0
endif
return(nResult)
Lets see if I can communicate this clearly,
and if others agree.
For a signed 32 bit number,
the high order bit is used as a flag to signify a negative number.
If we had an unsigned 32 bit number,
where only the high order bit was set,
and all other bits were 0,
the value would be 2 ^(32-1) = 2,147,483,648
So,again staying with unsigned number,
if we started with a value of 0,
and added 2,147,483,648....
it would set the high order bit to 1.
Now, shifting perspective,
if we look at these 4 bytes as a signed longint,
then the negative flag would be set,
because the odometer rolled over the highest number.
Paradox would evaluate that as a negative number,
In paradox, because we dont have unsigned longint,
we need to shift the calculations to number data type,
so that we dont lose numerical precision,
when we exceed the max value for longint.
We would need to add back "2^(32-1)" two times.
( 2,147,483,648+2,147,483,648 = 4294967296.0)
The first time, so that we return to our original number,
and then a second time so that it is added properly.
This time since we have shifted data type to number type,
we wont have an overflow issue and should get the correct answer.
Corrections and comments welcome.
Let the bits fly.
Robert Wiltshire
If we try to treat these 4 bytes as a longint,
issues can sometimes arise due to difference in
the way unsigned vs signed numbers are handled.
Lets say we end up having a longint, called liNum
If paradox reports that liNum < 0,
then the unsigned longint exceeds our singed longint max,
and therein lies the primary issue.
The goal is simply to calculate the proper result,
and place it into a variable called nResult
; move contents from allocated memory to liNum
RtlMoveMemoryInVar(liNum,liMemoryAddress,4)
if liNum >= 0
then
nResult = number(liNum)
else
nResult = number(liNum) + 4294967296.0
endif
return(nResult)
Lets see if I can communicate this clearly,
and if others agree.
For a signed 32 bit number,
the high order bit is used as a flag to signify a negative number.
If we had an unsigned 32 bit number,
where only the high order bit was set,
and all other bits were 0,
the value would be 2 ^(32-1) = 2,147,483,648
So,again staying with unsigned number,
if we started with a value of 0,
and added 2,147,483,648....
it would set the high order bit to 1.
Now, shifting perspective,
if we look at these 4 bytes as a signed longint,
then the negative flag would be set,
because the odometer rolled over the highest number.
Paradox would evaluate that as a negative number,
In paradox, because we dont have unsigned longint,
we need to shift the calculations to number data type,
so that we dont lose numerical precision,
when we exceed the max value for longint.
We would need to add back "2^(32-1)" two times.
( 2,147,483,648+2,147,483,648 = 4294967296.0)
The first time, so that we return to our original number,
and then a second time so that it is added properly.
This time since we have shifted data type to number type,
we wont have an overflow issue and should get the correct answer.
Corrections and comments welcome.
Let the bits fly.
Robert Wiltshire