by Rde (54 Submissions)
Category: Math/Dates
Difficulty: Advanced
Date Added: Wed 3rd February 2021
Rating: (2 Votes)
Function to enable valid addition and subtraction of unsigned long integers. Treats the passed value as an unsigned long and returns an unsigned long. Allows safe arithmetic operations on memory address pointers. Assumes valid pointer and pointer offset. Rather fast too, has very small performance hit compared to unsafe in-line calculation, even in intensive loops. The code for addition came from VBC (LukeH) but I needed subtraction as well, thought I'd share. Confirmation that this produces valid results would be appreciated.
' Used for unsigned arithmetic
Private Const DW_MSB = &H80000000 ' DWord Most Significant Bit
' + Sum Unsigned Long ++++++++++++++++++++++
' Enables valid addition and subtraction of unsigned long integers.
' Treats lPtr as an unsigned long and returns an unsigned long.
' Allows safe arithmetic operations on memory address pointers.
' Assumes valid pointer and pointer offset.
Private Function SumUnsignedLong(ByVal lPtr As Long, ByVal lOffset As Long) As Long
If lOffset > 0& Then
If lPtr And DW_MSB Then ' if ptr < 0
SumUnsignedLong = lPtr + lOffset ' ignors > unsigned max (see assumption)
ElseIf (lPtr Or DW_MSB) < -lOffset Then
SumUnsignedLong = lPtr + lOffset ' result is below signed int max
Else ' result wraps to min signed int
SumUnsignedLong = (lPtr + DW_MSB) + (lOffset + DW_MSB)
End If
ElseIf lOffset = 0& Then
SumUnsignedLong = lPtr
Else 'If lOffset < 0 Then
If (lPtr And DW_MSB) = 0& Then ' if ptr > 0
SumUnsignedLong = lPtr + lOffset ' ignors unsigned < zero (see assumption)
ElseIf (lPtr - DW_MSB) >= -lOffset Then
SumUnsignedLong = lPtr + lOffset ' result is above signed int min
Else ' result wraps to max signed int
SumUnsignedLong = (lOffset - DW_MSB) + (lPtr - DW_MSB)
End If
End If
End Function
' ++++++++++++++++++++++++++++++++++++++++++
' Extract from the classic ShellSort algorithm
Dim s1 As String, lpStr1 As Long
Dim s2 As String, lpStr2 As Long
lpStr1 = VarPtr(s1)
lpStr2 = VarPtr(s2)
lpArr = VarPtr(sArr(lb))
'lpLast = lpArr + ((ub - lb) * 4&)
lpLast = SumUnsignedLong(lpArr, (ub - lb) * 4&)
'...
CopyMemByV lpStr1, lpLast, 4&
'CopyMemByV lpStr2, lpLast - lRange, 4&
CopyMemByV lpStr2, SumUnsignedLong(lpLast, -lRange), 4&
If StrComp(s2, s1, eMethod) = eComp Then
'...