' written by Kaze, 2022-Mar-15

' This EXE was made by running a modified (added -O3) recompile_win.bat (located in C:\qb64202\internal\temp):
' @echo off
' cd %0\..\
' echo Recompiling...
' cd ../c
' c_compiler\bin\g++ -O3 -mconsole -s -Wfatal-errors -w -Wall qbx.cpp  libqb\os\win\libqb_2_0.2_1001010001000.o  ..\..\.\internal\temp\icon.o -D DEPENDENCY_IMAGE_CODEC -D DEPENDENCY_NO_SOCKETS -D DEPENDENCY_NO_PRINTER -D DEPENDENCY_ICON -D DEPENDENCY_NO_SCREENIMAGE -D DEPENDENCY_LOADFONT -D DEPENDENCY_AUDIO_OUT  parts\video\font\ttf\os\win\src.o parts\audio\out\os\win\src.a   parts\core\os\win\src.a -lopengl32 -lglu32   -mwindows -static-libgcc -static-libstdc++ -D GLEW_STATIC -D FREEGLUT_STATIC     -lwinmm -lksguid -ldxguid -lole32 -lgdi32 -o "..\..\Quicksort_says.exe"
' pause

' This ELF was made by running a modified (added -O3) recompile_lnx.sh (located in qb64/internal/temp):
'[kaze@kaze qb64]$ cd /home/kaze/qb64/internal/temp
'[kaze@kaze temp]$ cat recompile_lnx.sh
'#!/bin/sh
'Pause()
'{
'OLDCONFIG=`stty -g`
'stty -icanon -echo min 1 time 0
'dd count=1 2>/dev/null
'stty $OLDCONFIG
'}
'echo "Recompiling..."
'cd ../c
'g++ -no-pie -w -O3 qbx.cpp  libqb/os/lnx/libqb_2_0.2_1000010001000.o  -D DEPENDENCY_IMAGE_CODEC -D DEPENDENCY_NO_SOCKETS -D DEPENDENCY_NO_PRINTER -D DEPENDENCY_ICON -D DEPENDENCY_NO_SCREENIMAGE -D DEPENDENCY_LOADFONT  parts/video/font/ttf/os/lnx/src.o parts/core/os/lnx/src.a -lGL -lGLU -lX11 -lpthread -ldl -lrt -D FREEGLUT_STATIC -o '../../Quicksort_says'
'echo "Press ENTER to exit..."
'Pause
'[kaze@kaze temp]$

_Define A-Z As _INTEGER64
_ControlChr Off 'without it couldn't _MAPUNICODE these 7, 9..13, 28..31

$Console
_Console Off
_Title "Quicksort benchmark, revision 14"
$ExeIcon:'ColumnChart.ico'
_Icon

Declare CustomType Library "qsm" ' Notice that 'CustomType' makes things work, using 'STATIC' gives errors during compilation
    Sub Quicksort_QB64_v14 (ByVal QWORDS As _Offset, Byval NumOfEle As _Integer64)
End Declare

'void * __cdecl memcpy (
'        void * dst,
'        const void * src,
'        size_t count
'        )

'Declare CustomType Library
'    Sub memcpy (ByVal dest As _Offset, Byval source As _Offset, Byval bytes As Long)
'End Declare
'a$ = "1234567890"
'b$ = "ABCDEFGHIJ"
'memcpy _Offset(a$) + 5, _Offset(b$) + 5, 5
'Print a$

$If WINDOWS Then
    Declare Library "mem"
    Function MemInUsePercent~&&
    Function TotalPhysicalMem~&&
    Function FreePhysicalMem~&&
    Function TotalPagingFile~&&
    Function FreePagingFile~&&
    Function TotalVirtualMem~&&
    Function FreeVirtualMem~&&
    Function FreeExtendedMem~&&
    Function GetCPULoad#
    End Declare
$End If

_ScreenMove 102, 3
XdimCOL = 64 + 30
YdimROW = 31

img& = _LoadImage("Sir_Tony_Hoare_and_Sanmayce_.png", 32)
Screen img&
_Delay 3

$If WIN Then
    Const Slash = "\"
$Else
    Const Slash = "/"
$End If

$If WINDOWS Then
    PSPlike$ = _CWD$ + "\"
$Else
    PSPlike$ = _CWD$ + "/"
$End If

handle& = _NewImage(XdimCOL, YdimROW, 0)
Screen handle&
_Dest handle&
_Font _LoadFont(PSPlike$ + "Px437_Cordata_PPC-400.ttf", 32, "MONOSPACE") '2021-Apr-23, use it on old laptops with 1680- by x, it is 6x12
GoSub SetColorScheme
Color 3

Print "________        .__        __                         __                                 "
Print "\_____  \  __ __|__| ____ |  | __  __________________/  |_    ___________  ___.__. ______"
Print " /  / \  \|  |  \  |/ ___\|  |/ / /  ___/  _ \_  __ \   __\  /  ___/\__  \<   |  |/  ___/"
Print "/   \_/.  \  |  /  \  \___|    <  \___ (  <_> )  | \/|  |    \___ \  / __ \\___  |\___ \ "
Print "\_____\ \_/____/|__|\___  >__|_ \/____  >____/|__|   |__|   /____  >(____  / ____/____  >"
Print "       \__>             \/     \/     \/                         \/      \/\/         \/ "

'Print " _____                   _                         _       ___                         _                              _     "
'Print "(  _  )        _        ( )                       ( )_    (  _`\                      ( )                            ( )    "
'Print "| ( ) | _   _ (_)   ___ | |/')   ___    _    _ __ | ,_)   | (_) )   __    ___     ___ | |__    ___ ___     _ _  _ __ | |/') "
'Print "| | | |( ) ( )| | /'___)| , <  /',__) /'_`\ ( '__)| |     |  _ <' /'__`\/' _ `\ /'___)|  _ `\/' _ ` _ `\ /'_` )( '__)| , <  "
'Print "| (('\|| (_) || |( (___ | |\`\ \__, \( (_) )| |   | |_    | (_) )(  ___/| ( ) |( (___ | | | || ( ) ( ) |( (_| || |   | |\`\ "
'Print "(___\_)`\___/'(_)`\____)(_) (_)(____/`\___/'(_)   `\__)   (____/'`\____)(_) (_)`\____)(_) (_)(_) (_) (_)`\__,_)(_)   (_) (_)"

'ditto = 3
ditto = 100 ' How many times to duplicate the original file of 22338618 elements/digits

Print

$If WINDOWS Then
    i = 0
    Do
    i = i + 1
    setting$ = Environ$(i) ' get a setting from the list
    If InStr(setting$, "NUMBER_OF_PROCESSORS") Then NUMBER_OF_PROCESSORS$ = setting$
    Loop Until setting$ = ""
    Print NUMBER_OF_PROCESSORS$

    ' For some reason the Drag-and-Drop stops working when running as Administrator?! [
    'C$ = ENVIRON$("ALLUSERSPROFILE") 'try desktop for all users
    'SHORTCUT$ = C$ + "\Desktop\" + "Masakari.log.txt" 'create filename for the desktop
    ' For some reason the Drag-and-Drop stops working when running as Administrator?! ]
$End If

Print "Current working directory path: "; Chr$(34); _StartDir$; Chr$(34)
Print "User's program calling path: "; Chr$(34); _CWD$; Chr$(34)

_Display
$If WINDOWS Then
    Play "v30l32c"
$End If
PostfixedToHeader = CsrLin
Do

    Locate PostfixedToHeader, 1
    $If WINDOWS Then
        ' MEMUSAGE by Steve [
        ' GetCPULoad = 0 is idle, 1 is fully used.
        '  Multiply by 100 for a percentage
        Print
        Print "CPU used:              "; LTrim$(Str$(Int((GetCPULoad * 10000) / 100))); "%"; Space$(18)
        Print "Memory used:           "; LTrim$(Str$(MemInUsePercent)); "%"; Space$(18)
        Print "Total Physical Memory: ";: Print AddCommas$(TotalPhysicalMem); " bytes"; Space$(18)
        Print "Free Physical Memory:  ";: Print AddCommas$(FreePhysicalMem); " bytes"; Space$(18)
        Print "Total Paging File:     ";: Print AddCommas$(TotalPagingFile); " bytes"; Space$(18)
        Print "Free Paging File:      ";: Print AddCommas$(FreePagingFile); " bytes"; Space$(18)
        '        PRINT "Total Virtual Memory:  ";: PRINT AddCommas$(TotalVirtualMem); " bytes"; SPACE$(18)
        '        PRINT "Free Virtual Memory:   ";: PRINT AddCommas$(FreeVirtualMem); " bytes"; SPACE$(18)
        ' MEMUSAGE by Steve ]
    $End If
    Print: Print "Press 'Enter' to commence sorting..."
    _Display
    _Limit 10
Loop While InKey$ <> Chr$(13)

Print: Print "Quicksort benchmark - testing speed for "; AddCommas$(22338618 * ditto); " QWORDS i.e. "; AddCommas$(22338618 * ditto * 8 \ 1024 \ 1024); " MB pool"
Print "Loading the dataset (few unique keys)... ";: _Display
ReDim FabriceBellard_DIGITS~&&(0 To 22338618 - 1)
ReDim QWORDS~&&(0 To 22338618 * ditto - 1)
Open "22338618_QWORDS.bin" For Binary As #1
'Open "22338618_QWORDS.bin.sorted" For Binary As #2
'For i = 0 To 22338618 - 1
'Get #1, , QWORDS~&&(i)
'Next
Get #1, , FabriceBellard_DIGITS~&&()
Print "Sorting the dataset...": _Display
BestTime~&& = -1
For k = 1 To 2
    For i = 1 To ditto
        For j = 0 To 22338618 - 1
            QWORDS~&&(22338618 * (i - 1) + j) = FabriceBellard_DIGITS~&&(j)
        Next j
    Next i
    Beg = Timer
    Do While Beg = Timer: Loop: Beg = Timer ' start afresh
    Select Case k
        Case 1:
            Call QuickSort(LBound(QWORDS~&&), UBound(QWORDS~&&), QWORDS~&&())
        Case 2:
            'Call Quicksort_QB64_v3(QWORDS~&&())
            Quicksort_QB64_v14 _Offset(QWORDS~&&(LBound(QWORDS~&&))), 1 + UBound(QWORDS~&&) - LBound(QWORDS~&&) ' with 'STATIC' library: error: invalid conversion from 'unsigned int' to 'void*' [-fpermissive] Quicksort_QB64_v4(((uptrszint)((&(((uint64*)(__ARRAY_UINTEGER64_QWORDS[0]))
    End Select
    Fin = Timer
    Print "Run #"; LTrim$(Str$(k)); ": in"; Fin - Beg; "seconds; ";:
    Print "Checking whether the sort is correct... ";
    UniqueElements = 1
    Previous = QWORDS~&&(0)
    For i = 0 To UBound(QWORDS~&&) - 1
        If QWORDS~&&(i) > QWORDS~&&(i + 1) Then Print "NOT OK!": End
        If Previous <> QWORDS~&&(i) Then UniqueElements = UniqueElements + 1: Previous = QWORDS~&&(i)
    Next
    Print "OK.";: Print " Unique keys = "; AddCommas$(UniqueElements)
    _Display
    If Fin - Beg < BestTime~&& Then BestTime~&& = Fin - Beg
Next k

ReDim FabriceBellard_DIGITS~&&(0 To 0)
ReDim QWORDS~&&(0 To 0)
Open "mobythesaurus.txt" For Binary As #3 ' we need the lof(3)-8+1 QWORDS
NastyDelayIfNotInVariable = LOF(3)
ReDim BuildingBlocksQWORDS~&&(0 To (NastyDelayIfNotInVariable - 8 + 1) - 1)
Print: Print "Quicksort benchmark - testing speed for "; AddCommas$((NastyDelayIfNotInVariable - 8 + 1) * ditto); " QWORDS i.e. "; AddCommas$((NastyDelayIfNotInVariable - 8 + 1) * ditto * 8 \ 1024 \ 1024); " MB pool"
Print "Loading the dataset (many unique keys)... ";: _Display
For i = 0 To (NastyDelayIfNotInVariable - 8 + 1) - 1
    Get #3, i + 1, BuildingBlocksQWORDS~&&(i)
Next
ReDim QWORDS~&&(0 To (NastyDelayIfNotInVariable - 8 + 1) * ditto - 1)
Print "Sorting the dataset...": _Display
BestTime~&& = -1
For k = 1 To 2
    For i = 1 To ditto
        For j = 0 To (NastyDelayIfNotInVariable - 8 + 1) - 1
            QWORDS~&&((NastyDelayIfNotInVariable - 8 + 1) * (i - 1) + j) = BuildingBlocksQWORDS~&&(j)
        Next j
    Next i
    Beg = Timer
    Do While Beg = Timer: Loop: Beg = Timer ' start afresh
    Select Case k
        Case 1:
            Call QuickSort(LBound(QWORDS~&&), UBound(QWORDS~&&), QWORDS~&&())
        Case 2:
            'Call Quicksort_QB64_v3(QWORDS~&&())
            Quicksort_QB64_v14 _Offset(QWORDS~&&(LBound(QWORDS~&&))), 1 + UBound(QWORDS~&&) - LBound(QWORDS~&&) ' with 'STATIC' library: error: invalid conversion from 'unsigned int' to 'void*' [-fpermissive] Quicksort_QB64_v4(((uptrszint)((&(((uint64*)(__ARRAY_UINTEGER64_QWORDS[0]))
    End Select
    Fin = Timer
    Print "Run #"; LTrim$(Str$(k)); ": in"; Fin - Beg; "seconds; ";:
    Print "Checking whether the sort is correct... ";
    UniqueElements = 1
    Previous = QWORDS~&&(0)
    For i = 0 To UBound(QWORDS~&&) - 1
        If QWORDS~&&(i) > QWORDS~&&(i + 1) Then Print "NOT OK!": End
        If Previous <> QWORDS~&&(i) Then UniqueElements = UniqueElements + 1: Previous = QWORDS~&&(i)
    Next
    Print "OK.";: Print " Unique keys = "; AddCommas$(UniqueElements)
    _Display
    If Fin - Beg < BestTime~&& Then BestTime~&& = Fin - Beg
Next k

$If WINDOWS Then
    Play "v40o2l40geb"
$End If
_KeyClear 2
'Print: Print "Best time:"; BestTime~&&; "seconds": _Display

'Put #2, , QWORDS~&&() 'for some reason dumps ~1.4GB not the whole ~13GB data, perhaps a limitation demanding chunk-dumps
End

SetColorScheme:
'Colorscale .000..255:

'0   Black            0             0             0
'1   Dark Blue        0             0             168
'2   Dark Green       0             168           0
'3   Dark Cyan        0             168           168
'4   Dark Red         168           0             0
'5   Dark Magenta     168           0             168
'6   Dark Yellow      168           84            0
'7   Light Grey       168           168           168

'8+0 Dark Grey        84            84            84
'8+1 Blue             84            84            252
'8+2 Green            84            252           84
'8+3 Cyan             84            252           252
'8+4 Red              252           84            84
'8+5 Magenta          252           84            252
'8+6 Yellow           252           252           84
'8+7 White            252           252           252

'Colorscale 00..63:
'0   Black            0      0       0
'1   Dark Blue        0      0      42
'2   Dark Green       0     42       0
'3   Dark Cyan        0     42      42
'4   Dark Red        42      0       0
'5   Dark Magenta    42      0      42
'6   Dark Yellow     42     21       0
'7   Light Grey      42     42      42

'8+0 Dark Grey       21     21      21
'8+1 Blue            21     21      63
'8+2 Green           21     63      21
'8+3 Cyan            21     63      63
'8+4 Red             63     21      21
'8+5 Magenta         63     21      63
'8+6 Yellow          63     63      21
'8+7 White           63     63      63

'Colorscale
_PaletteColor 0, _RGB32(0, 0, 0)
_PaletteColor 1, _RGB32(0, 0, 168)
_PaletteColor 2, _RGB32(0, 168, 0)
_PaletteColor 3, _RGB32(0, 168, 168)
_PaletteColor 4, _RGB32(168, 0, 0)
_PaletteColor 5, _RGB32(168, 0, 168)
_PaletteColor 6, _RGB32(168, 84, 0)
_PaletteColor 7, _RGB32(168, 168, 168)

_PaletteColor 8, _RGB32(84, 84, 84)
_PaletteColor 9, _RGB32(84, 84, 252)
_PaletteColor 10, _RGB32(84, 252, 84)
_PaletteColor 11, _RGB32(84, 252, 252)
_PaletteColor 12, _RGB32(252, 84, 84)
_PaletteColor 13, _RGB32(252, 84, 252)
_PaletteColor 14, _RGB32(252, 252, 84)
_PaletteColor 15, _RGB32(252, 252, 252)

_PaletteColor 3, _RGB32(0, 168 - 10, 168 - 10) 'darker Cyan
_PaletteColor 8, _RGB32(84 - 22, 84 - 22, 84 - 22) 'make Grey darker

_PaletteColor 4, _RGB32(110, 2, 25) 'Carminish
_PaletteColor 4 + 8, _RGB32(110 + 44, 2 + 44, 25 + 44) 'make Carmin more lighter

_PaletteColor 1, _RGB32(168 - 20, 84 - 20, 0) 'make the Amber more darker
_PaletteColor 6 + 8, _RGB32(168 + 54, 84 + 54, 0) 'make the Amber more lighter

' Change the Purple to SteelBlue
_PaletteColor 5, _RGB32(33, 99, 122)
_PaletteColor 5 + 8, _RGB32(33 + 44, 99 + 44, 122 + 44)
' Change the Green to Cyanish
_PaletteColor 2, _RGB32(1, 80, 80)
_PaletteColor 2 + 8, _RGB32(1 + 44, 80 + 44, 80 + 44)

Return

Function AddCommas$ (numeral)
    s$ = LTrim$(Str$(numeral))
    If Len(s$) > 3 Then
        If (Len(s$) Mod 3) Then x$ = String$(3 - (Len(s$) Mod 3), " ") + s$ Else x$ = s$
        s$ = ""
        For i = 1 To Len(x$) Step 3
            s$ = s$ + Mid$(x$, i, 3) + ","
        Next
        s$ = Left$(s$, Len(s$) - 1)
    End If
    AddCommas$ = LTrim$(s$)
End Function

' Written by Sanmayce, 2021-Oct-29
' The indexes are signed, but the elements are unsigned.
_Define A-Z As _INTEGER64
Sub Quicksort_QB64 (QWORDS~&&())
    Left = LBound(QWORDS~&&)
    Right = UBound(QWORDS~&&)
    LeftMargin = Left
    ReDim Stack&&(Left To Right)
    StackPtr = 0
    StackPtr = StackPtr + 1
    Stack&&(StackPtr + LeftMargin) = Left
    StackPtr = StackPtr + 1
    Stack&&(StackPtr + LeftMargin) = Right
    Do 'Until StackPtr = 0
        Right = Stack&&(StackPtr + LeftMargin)
        StackPtr = StackPtr - 1
        Left = Stack&&(StackPtr + LeftMargin)
        StackPtr = StackPtr - 1
        Do 'Until Left >= Right
            Pivot~&& = QWORDS~&&((Left + Right) \ 2)
            Indx = Left
            Jndx = Right
            Do
                Do While (QWORDS~&&(Indx) < Pivot~&&)
                    Indx = Indx + 1
                Loop
                Do While (QWORDS~&&(Jndx) > Pivot~&&)
                    Jndx = Jndx - 1
                Loop
                If Indx <= Jndx Then
                    If Indx < Jndx Then Swap QWORDS~&&(Indx), QWORDS~&&(Jndx)
                    Indx = Indx + 1
                    Jndx = Jndx - 1
                End If
            Loop While Indx <= Jndx
            If Indx < Right Then
                StackPtr = StackPtr + 1
                Stack&&(StackPtr + LeftMargin) = Indx
                StackPtr = StackPtr + 1
                Stack&&(StackPtr + LeftMargin) = Right
            End If
            Right = Jndx
        Loop Until Left >= Right
    Loop Until StackPtr = 0
End Sub

_Define A-Z As _INTEGER64
Sub QuickSort (start As _Integer64, finish As _Integer64, array() As _Integer64)
    Lo = start: Hi = finish
    Middle = array((Lo + Hi) \ 2)
    Do
        Do While array(Lo) < Middle: Lo = Lo + 1: Loop
        Do While array(Hi) > Middle: Hi = Hi - 1: Loop
        If Lo <= Hi Then
            Swap array(Lo), array(Hi)
            Lo = Lo + 1: Hi = Hi - 1
        End If
    Loop Until Lo > Hi
    If Hi > start Then Call QuickSort(start, Hi, array())
    If Lo < finish Then Call QuickSort(Lo, finish, array())
End Sub

' Written by Sanmayce, 2021-Nov-06
' The indexes are signed, but the elements are unsigned.
_Define A-Z As _INTEGER64
Sub Quicksort_QB64_v3 (QWORDS~&&())
    InsertionsortTHRESHOLD = 0 '19
    Left = LBound(QWORDS~&&)
    Right = UBound(QWORDS~&&)
    ReDim Stack&&(Left To Right)
    StackPtr = 0
    StackPtr = StackPtr + 1
    Stack&&(StackPtr + LeftMargin) = Left
    StackPtr = StackPtr + 1
    Stack&&(StackPtr + LeftMargin) = Right
    Do 'Until StackPtr = 0
        Right = Stack&&(StackPtr)
        Left = Stack&&(StackPtr - 1)
        StackPtr = StackPtr - 2
        Do 'Until Left >= Right

            ''Classica' partitioning [
            'Pivot~&& = QWORDS~&&((Left + Right) \ 2)
            'Indx = Left
            'Jndx = Right
            'Do
            '    Do While (QWORDS~&&(Indx) < Pivot~&&)
            '        Indx = Indx + 1
            '    Loop
            '    Do While (QWORDS~&&(Jndx) > Pivot~&&)
            '        Jndx = Jndx - 1
            '    Loop
            '    If Indx <= Jndx Then
            '        If Indx < Jndx Then Swap QWORDS~&&(Indx), QWORDS~&&(Jndx)
            '        Indx = Indx + 1
            '        Jndx = Jndx - 1
            '    End If
            'Loop While Indx <= Jndx
            ''Classica' partitioning ]

            ' 'Magnetica' partitioning [
            Jndx = Right
            PL = Left
            PR = Left
            Swap QWORDS~&&((Left + Right) \ 2), QWORDS~&&(PR)
            Pivot~&& = QWORDS~&&(PR)
            Do While PR < Jndx
                If Pivot~&& > QWORDS~&&(PR + 1) Then
                    Swap QWORDS~&&(PL), QWORDS~&&(PR + 1)
                    PL = PL + 1
                    PR = PR + 1
                ElseIf Pivot~&& = QWORDS~&&(PR + 1) Then
                    PR = PR + 1
                Else ' < i.e. Pivot~&& < QWORDS~&&(PR + 1)
                    Do While Pivot~&& < QWORDS~&&(Jndx)
                        Jndx = Jndx - 1
                    Loop
                    If PR + 1 < Jndx Then Swap QWORDS~&&(PR + 1), QWORDS~&&(Jndx)
                    Jndx = Jndx - 1
                End If
            Loop
            Jndx = PL - 1
            Indx = PR + 1
            ' 'Magnetica' partitioning ]

            If Indx + InsertionsortTHRESHOLD < Right Then 'if the remaining chunk is bigger than 'InsertionsortTHRESHOLD' push it to stack, otherwise leave all such chunks unsorted
                StackPtr = StackPtr + 2
                Stack&&(StackPtr - 1) = Indx
                Stack&&(StackPtr) = Right
            End If
            Right = Jndx
        Loop Until Left >= Right
    Loop Until StackPtr = 0
    'Left = LBound(QWORDS~&&)
    'Right = UBound(QWORDS~&&)
    'For i = Left + 1 To Right ' i.e. 1 to size-1 omitting the first (which is 0)
    '    j = i
    '    Do While j >= 1 'Nah, start using a sentinel
    '        If QWORDS~&&(j - 1) > QWORDS~&&(j) Then Swap QWORDS~&&(j - 1), QWORDS~&&(j) Else Exit Do
    '        j = j - 1
    '    Loop
    'Next i
End Sub

'Print ConvertOffset~&&(m.OFFSET)
Function ConvertOffset~&& (value As _Offset)
    $Checking:Off
    Dim m As _MEM 'Define a memblock
    m = _Mem(value) 'Point it to use value
    $If 64BIT Then
        'On 64 bit OSes, an OFFSET is 8 bytes in size.  We can put it directly into an Integer64
        _MemGet m, m.OFFSET, temp64~&& 'Get the contents of the memblock and put the values there directly into ConvertOffset&&
        ConvertOffset~&& = temp64~&&
    $Else
        'However, on 32 bit OSes, an OFFSET is only 4 bytes.  We need to put it into a LONG variable first
        _MemGet m, m.OFFSET, temp& 'Like this
        ConvertOffset~&& = temp& 'And then assign that long value to ConvertOffset&&
    $End If
    _MemFree m 'Free the memblock
    $Checking:On
End Function

