Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Need help with boolean
#1
Quick feature description:

The program encodes a text string into a binary string that is encoded in five bits. To achieve this, thanks to the MEM functions, I manipulate a variable of type _Integer64, where I fill the first 5 bytes with five bits, thereby placing 8 characters of the text string in these 5 bytes. Subsequently, I save the variable of type Integer64 in memory and in the next step I overwrite its last three bytes. This gives me a five-byte value that is not directly available in QB64. Finally, I extract the valid length from the memory to the string (for 8 characters it is 40 bits, so 5 bytes).

During decoding, the coded string is inserted into memory and is read from it using a string of five bytes, and thanks to the MEM options, this variable is inserted into a number of type Integer64. This number is then decomposed back into the individual array indices that determine the specific letters of the encoded string.

I have completely avoided the previous Dec2Bin and Bin2Dec practices here that you can see in my old programs.

While this whole thing was supposed to be a nice distraction and fun, it turned into a huge embarrassment. I really don't know what I neglected, that's why I want to ask you for help.

 Now if you run this program as is, it will work correctly. But. Please disable MemFill on line 81 and run it again.

Where do the artifacts come from? Where does the new memory array take those bogus values? I am not able to deduce it logically and I do not see it in the program (with my little knowledge of boolean operations). Can someone explain this to me?

Code: (Select All)

'S2FB$ - String to five bite string
'FB2S$ - five bite string back to normal 8 bit string
'allowed characters: abcdefghijklmnopqrstuvwxyz+- '

'can be expanded, but this is not implanted in this version.




txt$ = "text to five byte binary text coder and decoder - first version"
'
t$ = S2FB$(txt$) 'string to five byte code (return binary string code)

Do
    u$ = FB2S$(t$) 'decode binary string t$ to normal text u$
    Print u$
    t$ = S2FB$(txt$) 'make 5 bit coded string from normal text string txt$
    _Limit 20
Loop






Function S2FB$ (S As String) 'returns a binary string encoded in the form of an index in the range 0 to 31, where each number is encoded in five bits according to the internal character table
    Stable$ = "abcdefghijklmnopqrstuvwxyz+- '"
    Dim InputTable(Len(S$)) As _Unsigned _Byte
    i = 0
    For test = 1 To Len(S$)
        ch1$ = Mid$(S$, test, 1)
        Allow = 0
        For compare = 1 To Len(Stable$)
            ch2$ = Mid$(Stable$, compare, 1)
            If ch2$ = ch1$ Then
                Allow = 1
                InputTable(i) = compare 'set indexes to characters in S string
                i = i + 1
            End If
        Next compare
        If Allow = 0 Then Print "Can not create B5$. Unexpected character: "; ch1$: _Display: Sleep 3: End
    Next test

    Dim prd As _Unsigned _Integer64
    Dim me As _MEM
    If Len(S$) > 32 Then me = _MemNew(Len(S$)) Else me = _MemNew(32)
    j = 0
    meStep = 0
    prd = 0

    Do Until j > i
        For t = 1 To 7
            If j > UBound(InputTable) Then Exit For
            prd = prd Or InputTable(j)
            prd = _ShL(prd, 5)
            j = j + 1
        Next t
        _MemPut me, me.OFFSET + meStep, prd
        meStep = meStep + 5
        prd = 0
    Loop
    prd = 0
    Dim V As _Unsigned _Byte
    V = 0

    Code5$ = Space$(meStep)
    _MemGet me, me.OFFSET, Code5$
    S2FB$ = Code5$
    _MemFree me
    Erase InputTable
End Function


Function FB2S$ (code As String) ' Function decode binary string coded in 5 bite and return it as normal 8bit text.
    Stable$ = "abcdefghijklmnopqrstuvwxyz+- '"
    Dim me As _MEM
    MSize = Len(code) * 1.6
    If MSize < 16 Then MSize = 16
    me = _MemNew(MSize)
    _MemFill me, me.OFFSET, me.SIZE, 0 As _UNSIGNED _BYTE 'this is VERY VERY NEED HERE.
    _MemPut me, me.OFFSET, code$

    Dim hodnota As _Unsigned _Integer64
    Dim Vse As _Offset
    Dim Var As _MEM
    Dim prd As _Unsigned _Integer64
    prd = 0
    Var = _Mem(prd)
    If MSize < 5 Then swp$ = Space$(MSize) Else swp$ = Space$(5)
    outb$ = ""

    Vse = 0
    Do Until Vse > me.SIZE - 5
        uu = uu + 1
        _MemGet me, me.OFFSET + Vse, swp$
        _MemPut Var, Var.OFFSET, swp$
        ReDim swp(1 To 8) As _Unsigned _Byte

        For pr = 1 To 8
            hodnota = prd And 31
            swp(9 - pr) = hodnota
            prd = _ShR(prd, 5)
        Next

        For dis = 1 To 8
            outb$ = outb$ + Mid$(Stable$, swp(dis), 1)
        Next

        ReDim swp(1 To 8) As _Unsigned _Byte
        Vse = Vse + 5
        prd = 0
    Loop

    swp$ = ""
    FB2S$ = outb$
    _MemFree me
    _MemFree Var
End Function



Reply
#2
https://qb64phoenix.com/qb64wiki/index.php/MEMNEW

_MEMNEW does not clear the data previously in the memory block it allocates, for speed purposes.
To clear previous data from a new memory block, use _MEMFILL with a byte value of 0
Reply
#3
Well, I really didn't know. It didn't make sense to me, I thought - when there is a new memory block, it is simply new and clean, like a newly dimensioned field or a newly created screen....

I see that MEM commands have a different policy. Thank you for the explanation.


Reply
#4
Memnew just grabs a free spot in memory and reserves it for your use.  Now if that memory has always been unused, it's probably all 0s.  But if it's using a portion of memory that had been used previously and then freed, then it's going to have that old data in it.

Most of the time (like when creating an array), data goes through two steps: Reserve it and Initialize it.

Since Mem is optimized for speed, it skips that second step.

Instead of:  Reserve it.  Initialize it to 0.  Put data in it.
It is simply: Reserve it.  Put data in it.

I'm certain you can see where the second has to be faster than the first when running it.  The only problem comes if you read it before you fill it up with your own data.  You end up getting junk in it, as you've seen for yourself in your own stuff above.
Reply
#5
Well this is interesting and good to know should I get into memory stuff.
b = b + ...
Reply
#6
I always thought the song that went, "Memories... like the corners of my mind..." was for blockheads. Big Grin

Yeah, me too. Thanks for the _memories. I hope to use them someday .

Pete
Shoot first and shoot people who ask questions, later.
Reply
#7
Yes a good remark of syntax about _MEMFILL and _MEMNEW
It seems that wiki is clear that there is no initialization of memory block using _MEMNEW  
_Memnew wiki page

!!! Arghhh  I need more time to read Wiki pages, but the time saved with the right knowledge ( avoiding unexpected results)  is more than that spent to read wiki.
Reply




Users browsing this thread: 1 Guest(s)