Hello,
as the title says, what would be the most efficient way of converting a 20 bit 2's complement data, read from a sensor's registers, to SDword? The data is read from three 8bit sensor registers.
Thank you
There are several ways of sign extending, but the method below should work efficiently.
Dim DwordIn As Dword ' Holds the signed 20-bit value
Dim Dwordout As SDword ' Holds the sign extended 32-bit value
DwordIn = %00000000000011111111111111111111 ' Load Dwordin with a signed 20-bit value of -1
'
' Sign extend a 20-bit value to a 32-bit value
'
If DwordIn.19 = 1 Then ' Is the sign bit set?
Dwordout.Byte3 = %11111111 ' Yes. So set all of byte3
Dwordout.Byte2 = DwordIn.Byte2 | %11110000 ' Or in set bits of byte2
Dwordout.Byte1 = DwordIn.Byte1 ' Transfer byte1 to byte1
Dwordout.Byte0 = DwordIn.Byte0 ' Transfer byte0 to byte0
Else ' Otherwise... The value is not signed
Dwordout = DwordIn ' So transfer dwordin to dwordout
EndIf
Quote from: top204 on Jun 27, 2021, 06:11 PMThere are several ways of sign extending, but the method below should work efficiently.
Thank you Les, I know there was a better way than my For-Next loop and bit manipulation :)
Here's a tiny bit more efficient way, because it loads the lower 16-bits first, then alters the higher 16-bits, instead of transfering the lower 16-bits in each comparison.
Dim DwordIn As Dword ' Holds the signed 20-bit value
Dim Dwordout As SDword ' Holds the sign extended 32-bit value
DwordIn = %00000000000011111111111111111111 ' Load Dwordin with a signed 20-bit value of -1
'
' Sign extend a 20-bit value to a signed 32-bit value
'
Dwordout.Word0 = DwordIn.Word0 ' Transfer the lower 16-bits
If DwordIn.19 = 1 Then ' Is the sign bit set?
Dwordout.Byte3 = %11111111 ' Yes. So set all the bits of byte3
Dwordout.Byte2 = DwordIn.Byte2 | %11110000 ' Or in the permanently set bits of byte2
Else ' Otherwise... the value is not signed. So...
Dwordout.Word1 = DwordIn.Word1 ' Transfer the high 16-bits
EndIf
Here's an even more efficient method using a 24-bit Long variable to hold the 20-bit value. It saves about 6 bytes of code and operates a bit faster.
Dim LongIn As Long ' Holds the signed 20-bit value
Dim DwordOut As SDword ' Holds the sign extended 32-bit value
LongIn = %000011111111111111111111 ' Load LongIn with a signed 20-bit value of -1
'
' Sign extend a signed 20-bit value to a signed 32-bit value
'
DwordOut.Dword = LongIn ' Transfer the 20-bit value to unsigned DwordOut
If LongIn.19 = 1 Then ' Is the sign bit set?
DwordOut.Byte3 = %11111111 ' Yes. So set all the bits of byte3
DwordOut.Byte2 = LongIn.Byte2 | %11110000 ' Or in the permanently set bits of byte2
EndIf