B4R Question Bits rotation

Mostez

Active Member
Licensed User
I want to to rotate byte-bits, the resulting byte-bit-0 = source byte-bit7 and so on for next 7 bits
if i have a byte = 00001001 it should be = 10010000 after rotation, any ideas?
 

emexes

Well-Known Member
Licensed User
if i have a byte = 00001001 it should be = 10010000 after rotation, any ideas?
That looks more like a reflection.

A rotation to the right would be 10000100

A rotation to the left would be 00010010

If you are looking for a rotation, it sounds like you want it to be to the left, since you say bit 7 is transferred to bit 0. The easiest way to do that would be:

B4X:
X = 0x09    'binary 00001001 = hexadecimal 09 = decimal 9

X = X + X    'shift X one bit to the left (ie multiply-by-two) so X is now binary 000010010 = decimal 18
if X >= 256 then    'if bit 8 (just shifted out of bit 7) is set then
    X = X - 255        'clear bit 8 (subtract 256) and put it into bit 1 instead (add 1)
End If
 
Last edited:

Mostez

Active Member
Licensed User
I have font byte array, when I send font to graphics lcd, characters printed upside down, so i need to re-arrange bits in opposite order, what i need is like;
NewByte(bit0) = OldByte(bit7)
NewByte(bit1) = OldByte(bit6)
.
.
NewByte(bit7) = OldByte(bit0)
 

emexes

Well-Known Member
Licensed User
I have font byte array, when I send font to graphics lcd, characters printed upside down, so i need to re-arrange bits in opposite order, what i need is like;
NewByte(bit0) = OldByte(bit7)
NewByte(bit1) = OldByte(bit6)
.
.
NewByte(bit7) = OldByte(bit0)
How about this?...
B4X:
Dim ReflectByte(256)

For B0 = 0 to 1
For B1 = 0 to 1
For B2 = 0 to 1
For B3 = 0 to 1
For B4 = 0 to 1
For B5 = 0 to 1
For B6 = 0 to 1
For B7 = 0 to 1
    ReflectByte(B0 * 128 + B1 * 64 + B2 * 32 + B3 * 16 + B4 * 8 + B5 * 4 + B6 * 2 + B7) = B7 * 128 + B6 * 64 + B5 * 32 + B4 * 16 + B3 * 8 + B2 * 4 + B1 * 2 + B0
Next
Next
Next
Next
Next
Next
Next
Next

'and then you can just use that array as a lookup table:

NewByte = ReflectByte(OldByte)
 

emexes

Well-Known Member
Licensed User
I have font byte array, when I send font to graphics lcd, characters printed upside down, so i need to re-arrange bits in opposite order, what i need is like;
NewByte(bit0) = OldByte(bit7)
NewByte(bit1) = OldByte(bit6)
.
.
NewByte(bit7) = OldByte(bit0)
Or this:
B4X:
Sub ReflectByte(X As Int) As Int

    Dim OldByte as Int = Bit.And(X, 255)    'partly because I can't remember whether X is passed by value or reference
    Dim NewByte As Int = 0

    For B = 1 to 8    '8 bits
        NewByte = NewByte + NewByte    'shift left
        If Bit.And(OldByte, 1) <> 0 Then
            NewByte = NewByte + 1    'set bit 0
        End If
        OldByte = Bit.ShiftRight(OldByte, 1)
    Next

    Return NewByte

End Sub

For I = 0 to 255
    Log(I & " reflected = " & ReflectByte(I))
Next
 

Mostez

Active Member
Licensed User
here is what I did, it works OK,
B4X:
Dim tmB As Byte = 0
    Dim B As Byte
    Select Reflect
        Case REFLECT_BYTE_NONE
            tmB = cByte
        Case REFLECT_BYTE
            For B = 0 To 7
                If Bit.Get(cByte,B) = 1 Then Bit.Set(tmB,7 - B)
            Next
    End Select
 
Last edited:

emexes

Well-Known Member
Licensed User
here is what I did, it works OK
Indeed, that is simpler than my code, so:

:) :) :)

I'd like to test the relative speeds, but I don't have the Bit.Set and Bit.Get methods in the version of B4A that I'm running at the moment. I can see that they would be useful additions.
 
Last edited:

emexes

Well-Known Member
Licensed User
I don't have the Bit.Set and Bit.Get methods in the version of B4A that I'm running at the moment. I can see that they would be useful additions.
Just realised we're in the B4R forum.

With a bit of luck, those Bit methods might percolate through to B4A/J/I too.
 

emexes

Well-Known Member
Licensed User
If you're interested, a faster way might be:
B4X:
Sub ReflectByte(X As Int) As Int

    Dim Y As Int = X

    'bitmasks: 0x55 = 01010101   0x33 = 00110011   0x0F = 00001111
    '          0xAA = 10101010   0xCC = 11001100   0xF0 = 11110000
 
    Y = Bit.Or( Bit.ShiftLeft(Bit.And(Y, 0x55), 1), Bit.ShiftRight(Bit.And(Y, 0xAA), 1) )  'swap alternate 1-bit blocks
    Y = Bit.Or( Bit.ShiftLeft(Bit.And(Y, 0x33), 2), Bit.ShiftRight(Bit.And(Y, 0xCC), 2) )  'swap alternate 2-bit blocks
    Y = Bit.Or( Bit.ShiftLeft(Bit.And(Y, 0x0F), 4), Bit.ShiftRight(Bit.And(Y, 0xF0), 4) )  'swap alternate 4-bit blocks (nybbles within bytes)
 
    Return Y

End Sub
Presumably it'd be even faster in B4R if you changed the Ints to Bytes (whereas in Java, anything smaller than an Int is handled as an Int) (broadly speaking)

The advantage of this way is that each doubling of the data size, from 8 bits to 16 bits to 32 bits, adds just one line execution, rather than doubling, ie efficiency is O(log(n)) rather than O(n).
 
Last edited:

Mostez

Active Member
Licensed User
first, thank you so much for your valuable replies, you're right, I replaced the code in post #8
 

emexes

Well-Known Member
Licensed User
first, thank you so much for your valuable replies, you're right, I replaced the code in post #8
I feel like you've had it under control from the beginning anyway, but... if I knew how to put a thumbs-up emoji here, I would. Several, in fact!

I assume you'll be reflecting/reversing the bitmaps in the vertical direction too, but presumably that's a lot easier, especially if the bitmaps are 8 pixels wide (or some multiple thereof).
 
Top