B4R Question 32-bit bit operation library ? 64-bit ?

peacemaker

Expert
Licensed User
Longtime User
Hi, All

Do we have B4R code templates or library for working with 32 and 64-bit bit operations ?
 

peacemaker

Expert
Licensed User
Longtime User
Some my start, better to make a lib, i think, with all bit functions:

B4X:
#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: True
    #StackBufferSize: 5600
#End Region


Sub Process_Globals
    Public Serial1 As Serial
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Delay(2000)
    Log(CRLF, "AppStart")
    
    Dim source As ULong = 4294967295    '0xFFFFFFFF
    Log("Source: " , source, ": ", BinaryToString_ULong(source))
    For i = 1 To 31
        Dim res As ULong = ShiftRight32(source, i)
        Log("Res, right ", NumberFormat(i, 2, 0),": ", BinaryToString_ULong(res))
    Next
    
    For i = 1 To 31
        Dim res As ULong = ShiftLeft32(source, i)
        Log("Res, left ", NumberFormat(i, 2, 0),": ", BinaryToString_ULong(res))
    Next
End Sub

Sub LogNumber(name As String, v As ULong)
    Dim Binary As String = BinaryToString_ULong(v)
    Log(name, ": ", v, "; Binary = ", Binary)
End Sub

Sub ShiftRight32(Value As ULong, Shift As Byte) As ULong
    If Shift >= 32 Then Return 0
    If Shift = 0 Then Return Value
    
    ' Split into two 16-bit parts
    Dim lowWord As UInt = Bit.And(Value, 0xFFFF)
    Dim highWord As UInt = (Value - lowWord) / 65536 ' Alternative to ShiftRight for ULong
    
    If Shift < 16 Then
        ' Calculate carry bits from high to low
        Dim carryMask As UInt = Bit.ShiftLeft(1, Shift) - 1
        Dim carryBits As UInt = Bit.And(highWord, carryMask)
        carryBits = Bit.ShiftLeft(carryBits, 16 - Shift)
        
        ' Shift both parts
        Dim newHigh As UInt = Bit.ShiftRight(highWord, Shift)
        Dim newLow As UInt = Bit.Or(Bit.ShiftRight(lowWord, Shift), carryBits)
        
        ' Combine back
        Return (newHigh * 65536) + newLow
    Else
        ' Only shift high word
        Return Bit.ShiftRight(highWord, Shift - 16)
    End If
End Sub

Sub ShiftLeft32(Value As ULong, Shift As Byte) As ULong
    If Shift >= 32 Then Return 0
    If Shift = 0 Then Return Value
    
    ' Split into two 16-bit parts
    Dim lowWord As UInt = Bit.And(Value, 0xFFFF)
    Dim highWord As UInt = (Value - lowWord) / 65536
    
    If Shift < 16 Then
        ' Calculate carry bits from lowWord to highWord
        Dim carryBits As UInt = Bit.ShiftRight(lowWord, 16 - Shift)
        
        ' Shift both parts
        Dim newLow As UInt = Bit.ShiftLeft(lowWord, Shift)
        Dim newHigh As UInt = Bit.Or(Bit.ShiftLeft(highWord, Shift), carryBits)
        
        ' Combine back
        Return (newHigh * 65536) + newLow
    Else If Shift < 32 Then
        ' Only shift lowWord, carry to highWord
        Dim newHigh As UInt = Bit.ShiftLeft(lowWord, Shift - 16)
        Return newHigh * 65536 ' newLow = 0
    Else
        Return 0
    End If
End Sub

Sub BinaryToString_ULong(value As ULong) As String
    Dim result As String = "0b"
    Dim i As Int
    
    ' Process high word (bits 31-16)
    Dim highWord As UInt = (value - Bit.And(value, 0xFFFF)) / 65536
    For i = 15 To 0 Step -1
        Dim mask As UInt = Bit.ShiftLeft(1, i)
        If Bit.And(highWord, mask) <> 0 Then
            result = JoinStrings(Array As String(result, "1"))
        Else
            result = JoinStrings(Array As String(result, "0"))
        End If
    Next
    
    ' Process low word (bits 15-0)
    Dim lowWord As UInt = Bit.And(value, 0xFFFF)
    For i = 15 To 0 Step -1
        Dim mask As UInt = Bit.ShiftLeft(1, i)
        If Bit.And(lowWord, mask) <> 0 Then
            result = JoinStrings(Array As String(result, "1"))
        Else
            result = JoinStrings(Array As String(result, "0"))
        End If
    Next
    
    Return result
End Sub

Sub BitAnd_ULong(a As ULong, b As ULong) As ULong
    ' Split into words using division instead of shifting
    Dim aLow As UInt = Bit.And(a, 0xFFFF)
    Dim aHigh As UInt = (a - aLow) / 65536
    Dim bLow As UInt = Bit.And(b, 0xFFFF)
    Dim bHigh As UInt = (b - bLow) / 65536
    
    ' Perform 16-bit operations
    Dim resLow As UInt = Bit.And(aLow, bLow)
    Dim resHigh As UInt = Bit.And(aHigh, bHigh)
    
    ' Combine results
    Return (resHigh * 65536) + resLow
End Sub

Sub BitOr_ULong(a As ULong, b As ULong) As ULong
    Dim aLow As UInt = Bit.And(a, 0xFFFF)
    Dim aHigh As UInt = (a - aLow) / 65536
    Dim bLow As UInt = Bit.And(b, 0xFFFF)
    Dim bHigh As UInt = (b - bLow) / 65536
    
    Dim resLow As UInt = Bit.Or(aLow, bLow)
    Dim resHigh As UInt = Bit.Or(aHigh, bHigh)
    
    Return (resHigh * 65536) + resLow
End Sub
 
Upvote 0

candide

Active Member
Licensed User
from my understanding , long size is depending of processor, and on esp32 it is 64bits.

to avoid different sizes with arduino, we can use int8_t, int16_t, int32_t, int64_t, and size is clear for all processors
=> can we have it in B4R ?

also, float 4 bytes and double 8 bytes should be interesting...

can we extend rCore.h ?
 
Upvote 0
Top