Copying 6 bit data in a 6 element array into a 5 element, 8 bit array

Started by John Lawton, Sep 06, 2021, 06:01 PM

Previous topic - Next topic

John Lawton

I'm scratching my head as to the best way to copy 6 bit data held in a 6 element array (i.e. 36 bits in all) into another 5 element byte array, i.e. without any gaps (except for the most significant 4 bits in the last array element).

The data to copy is the lowest 6 bits of each source byte, (i.e. ignoring bits 6 & 7).
I can't think of an elegant way to do this, but speed is the most important factor rather than code size.

Any ideas?

RGV250

Hi,
Just going out for a beer but how about having an intermediate Word, you can copy the lowest 6 bits straight to the array but for the next ones copy the second / third / fourth etc 6 bits in to the second byte of the Word and shift right by 2. Then copy the second byte to the second element of the array and AND the first element of the array and so on to move the lowest 2 bits and so on. Just remember to clear the temp word each time.

I am sure someone will come up with a slicker and neater way but just my thoughts.

Regards,
Bob

RGV250

Another thought is to have a loop and just test the relevant bit of the 6 element array and set/reset the relevant bit in the 5 element array.

Bob

top204

I'm not too sure of your LSB and MSB, but the code below compresses 6-bit values held in one array, into another smaller array, and because it uses inline coding, it is fast.

See how an array's elements can be accessed as seperate variables for more speed and flexability? I think this is unique to the Positron compilers, and I created arrays like that from the compiler's first creation, so no RAM was wasted in blocks with no access to them because the early PIC microcontrollers had very little RAM to waste, but it is still very useful and very flexible and very fast to use, even on PIC24 and dsPIC33 devices. :-)

The code displays, on a serial terminal, the original binary values held in Source, then below it, the compressed binaries held in Dest. It will be easy to change if the LSB and MSB are different because it is just a series of shifts and ORing in the bits. The code could be placed in a procedure, so a single call will shift the data around to/from global arrays, or indirectly using the PtrX functions and the ByRef parameters directive so the source and destination arrays can be chosen at will.

' Move 6-bit values from an array to a smaller array where the bits are compressed into a single value
' Written by Les Johnson for the Positron8 BASIC compiler
'
    Device = 18F25K20
    Declare Xtal = 16
'
' Setup USART1
'
    Declare Hserial1_Baud = 9600            ' Setup the Baud rate of USART1
    Declare HRSOut1_Pin = PORTB.6           ' Setup the pin used for USART1 TX
'
' Create some variables
'
    Dim Source[6] As Byte = %00100001, %00100010, %00100011, %00100100, %00100101, %00100110
    'Dim Source[6] As Byte = %00111100, %00111100, %00111100, %00111100, %00111100, %00111100
    Dim Dest[5] As Byte
    Dim wTemp As Word
    
'----------------------------------------------------------------
Main:
    HRSOutLn Bin6 Source#5, " ", Bin6 Source#4, " ", Bin6 Source#3, " ", Bin6 Source#2, " ", Bin6 Source#1, " ", Bin6 Source#0
      
    Dest#4 = Source#5 << 2                      ' Load Dest#4 with the shifted Source#5
   
    wTemp = Source#4 << 4                       ' Shift the MSB bits into the high byte of wTemp
    Dest#4 = Dest#4 | wTemp.Byte1               ' Or in the shifted bits
    Dest#3 = wTemp.Byte0
   
    wTemp = Source#3 << 6                       ' Shift the MSB bits into the high byte of wTemp
    Dest#3 = Dest#3 | wTemp.Byte1               ' Or in the shifted bits
    Dest#2 = wTemp.Byte0
   
    wTemp = Source#2 << 8                       ' Shift the MSB bits into the high byte of wTemp
    Dest#2 = Dest#2 | wTemp.Byte1               ' Or in the shifted bits
    Dest#1 = wTemp.Byte0
   
    wTemp = Source#1 << 10                      ' Shift the MSB bits into the high byte of wTemp
    Dest#1 = Dest#1 | wTemp.Byte1               ' Or in the shifted bits
    Dest#0 = wTemp.Byte0
   
    wTemp = Source#0 << 4                       ' Shift the MSB bits into the high byte of wTemp
    Dest#1 = Dest#1 | wTemp.Byte1               ' Or in the shifted bits
    Dest#0 = Dest#0 | wTemp.Byte0               ' Or in the bits remaining
   
    HRSOutLn Bin8 Dest#4, " ", Bin8 Dest#3, " ", Bin8 Dest#2, " ", Bin8 Dest#1, " ", Bin8 Dest#0
    Stop

Without the HRsoutLn commands and the Stop command, and the pre-loading of the Source array, the conversion only takes 136 bytes of flash. Not bad at all!

John Lawton

Many thanks everyone, food for thought.

Les, sorry I should have given some example data, my source 6 bit values are held in the bottom of the bytes, as in your code.
Oh, by the way, I like the new(?)  array syntax, Source#n in stead of Source[n] :)

John

trastikata

This is similar to Les' example, with bi-twise shifting back and forward, except the "Or"-ing is replaced with byte substitution, I don't know if it will be faster or not.

Dim InArray[6] As Byte
Dim OutArray[5] As Byte
Dim dTemp As Dword

dTemp = 0

dTemp.Byte0 = InArray[0]
dTemp.Byte0 = dTemp.Byte0 << 2

dTemp.Byte1 = InArray[1]
dTemp.Byte1 = dTemp.Byte1 << 2

dTemp.Byte2 = InArray[2]
dTemp.Byte2 = dTemp.Byte2 << 2

dTemp.Byte3 = InArray[3]
dTemp.Byte3 = dTemp.Byte3 << 2   

dTemp = dTemp >> 8     
OutArray[0] = dTemp.Byte0
OutArray[1] = dTemp.Byte1
OutArray[2] = dTemp.Byte2

dTemp = 0
dTemp.Byte0 = InArray[4]
dTemp.Byte0 = dTemp.Byte0 << 2

dTemp.Byte1 = InArray[5]
dTemp.Byte1 = dTemp.Byte1 << 2

dTemp = dTemp >> 4
OutArray[3] = dTemp.Byte0
OutArray[4] = dTemp.Byte1
 

John Lawton

Thanks Trastikata, another interesting way and more food for thought. I have also thought of a scheme using a 32 bit variable as my output variable. I would OR my 6bits of data with the bottom output variable byte and then shift it up 6 places and then repeat till all 32 bits are full.
I could then copy each byte across in order into my output array elements.
It'll be interesting to see which is the quickest method, although any should be fast enough.

John