#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