How to put both x & y inside one int

Jimmy

Active member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
715
This is a simple example on how to put both x & y inside one int
It also shows you how to create an efficient stack, without security checks.

This way we can shove away many coordinates with great speed and less memory.

Code:
' -------------------------------------------------------------
' Say that we want to push a lot of positions efficiently
' x & y can each be 0-16383 in this example
' -------------------------------------------------------------

Strict

    Global data:Int[65535]           ' Create a stack
    Global sp:Int = 32768            ' Create a stack pointer, prepared for a circular datastack

Function Main:Int()

    Local x:Int = 10 ' Set coordinates
    Local y:Int = 100

    ' PUSH X,Y -------------------------------
    sp = sp - 1 ; data[sp] = ( (x Shl 14) + y)
    ' ------------------------------------------

    x = 435833 ' destroy coordinates
    y = 34894

    ' POP X,Y ---------------------------------------------------------------------
    Local m:Int = data[sp] ; sp = sp + 1 ; x = (m Shr 14) & 16383 ; y = m & 16383
    ' ------------------------------------------------------------------------------

    Print x ' Proove that we have restored the coordinates
    Print y

    Return 0       
End
 
Last edited:

MikeHart

Administrator
Joined
Jun 19, 2017
Messages
3,035
Interesting approach and I can see a use case in data transmission over the internet where sending as less data as possible is important.
 

SLotman

Active member
3rd Party Module Dev
Joined
Jul 3, 2017
Messages
173
Why shift left 14 and not 16?

32768 = 2 ^16, not 14. You should do (y shl 16) + x to store two 'small ints' in there - and that will only work if values are>=0 - if you're working with negative values that will break down if you don't use at least 1 bit for the signal.
 

Jimmy

Active member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
715
The original 14-bit works 100% reliably.

But going to 15-bit and 16-bit now :
Using the full range must come with a warning. I made lots of tests before and they all point to that the full bit range does not work as you would expect, you'd might as well limit yourself and be safe with the 14-bit version. I would consider everything else unusable.

I did all these tests last week, I re-made a few tests this morning seeing the reaction post.

Note, why 15-bit work as bad as 16-bit which I cannot explain. If I had to guess It might be because the fact that we're dealing with two numbers so we need two ("sign") bits extra space.

Code:
Strict

    Global data:Int[65535]           ' Create a stack
    Global sp:Int = 32768            ' Create a stack pointer, prepared for a circular datastack

Function Main:Int()

    Local x:Int = 10000 ' Set coordinates
    Local y:Int = 100000

    ' Twos complement (same as a xs = -xs)
    Local xs:Int = 0
    xs = x -1
    xs =  xs ~ -1
    Print "----"
    Print xs
    Print "----"

    ' PUSH X,Y -------------------------------
  '  x = x + 65536 ; y = y + 65536
    sp = sp - 1 ; data[sp] = ( (x Shl 16) + y)
    ' ------------------------------------------

    x = 435833 ' destroy coordinates
    y = 34894

    ' POP X,Y ---------------------------------------------------------------------
    Local m:Int = data[sp] ; sp = sp + 1 ; x = (m Shr 16) & 65535 ; y = m & 65535
   ' x = x - 65536 ; y = y - 65536
    ' ------------------------------------------------------------------------------

    Print x
    Print y

    Return 0 
End
 
Last edited:
Top Bottom