B4J Question very basic question about bytes

giggetto71

Active Member
Licensed User
Longtime User
Hi all,
I have a very basic (most probably stupid..) question.
I am using the bit object to manipulate the bits inside a byte that I must then write to a sensor (which has a memory byte-organized).
I am using the below sub to set/reset the bit within my byte:
B4X:
Sub SetBit(b As Byte, index As Int, value As Boolean) As Byte
    If value Then
        Return Bit.Or(b, Bit.ShiftLeft(1, index))
    Else
        Return Bit.And(b, Bit.Not(Bit.ShiftLeft(1, index)))
    End If
End Sub

Here the problem. If I run the below code
B4X:
dim b0 as byte
b0=SetBit(b0,0,True)
b0=SetBit(b0,7,True)
Log(Bit.ToBinaryString(b0))

I would expect b0 to be:

10000001 (129 or 0x81)

after all b0 is a byte..
but what I get is:

11111111111111111111111110000001

Now. If I do the same with bit 0 and bit 6, everything works as expected and b0 stays byte..
It looks to me that, since the Bit.Or and Bit.Not,etc. work (return and get as input) with "int", they "cast" my byte into a INT (32 bit or 4 bytes).

Any idea?
thank you very much.
 

ac9ts

Active Member
Licensed User
Longtime User
And to add to the mystery:

Running:
B4X:
    Dim b0 As Byte=0
    For x=0 To 7
        b0=SetBit(b0,x,True)
        Log("b0 = " & b0 & " (" & Bit.ToBinaryString(b0) & ")")
    Next

produces:
Waiting for debugger to connect...
Program started.
b0 = 1 (1)
b0 = 3 (11)
b0 = 7 (111)
b0 = 15 (1111)
b0 = 31 (11111)
b0 = 63 (111111)
b0 = 127 (1111111)
b0 = -1 (11111111111111111111111111111111)


And setting each bit against 0 using:
B4X:
    Dim b0 As Byte=0
    For x=0 To 7
        b0=0
        b0=SetBit(b0,x,True)
        Log("b0 = " & b0 & " (" & Bit.ToBinaryString(b0) & ")")
    Next

produces:
Waiting for debugger to connect...
Program started.
b0 = 1 (1)
b0 = 2 (10)
b0 = 4 (100)
b0 = 8 (1000)
b0 = 16 (10000)
b0 = 32 (100000)
b0 = 64 (1000000)
b0 = -128 (11111111111111111111111110000000)
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
I am not overly familiar with bit/byte manipulation, but I think with all the conversion to Int each time you will just need to mask the output:

B4X:
Log(Bit.ToBinaryString(Bit.And(b0,0xff)))
 
Upvote 0

emexes

Expert
Licensed User
Bytes are signed in B4A/I/J. Setting bit 7 makes it a negative number. The Bit. operations are 32-bit (Java Ints) and thus the sign bit is extended when the function argument b0 is enlarged (aka cast) from 8 bits to 32 bits.

It would be great if there was an option for unsigned bytes, but... there is not.

What you can do is replace Bit.ToBinaryString(b0) with Bit.ToBinaryString( Bit.And(b0, 0xFF) )

edit: as per stevel05 whose more-concise reply beat mine by about 3 seconds :)
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Don't forget bytes in java are signed.
 
Upvote 0

ac9ts

Active Member
Licensed User
Longtime User
After a bit (pardon the pun) of digging, I discovered the same thing that @stevel05 knew. Bytes are signed (-128 to 127)
 
Upvote 0
Top