Rotate vs Shift
#1
Folks seem to be asking, "What's _ROL and _ROR?  How are the different from the bit shifting routines for _SHL and _SHR?"

Now you can learn the difference!

Code: (Select All)
Screen _NewImage(1024, 720, 32)
_Delay .5
_ScreenMove _Middle
$Color:32

Const Delay = 3

f = _LoadFont("courbd.ttf", 128, "monospace")
f1 = _LoadFont("courbd.ttf", 32, "monospace")
_Font f1

One = TextToImage("1", f, Yellow, Transparent, 1)
Zero = TextToImage("0", f, Green, Transparent, 1)
Cliff = TextToImage("        ", f, BrickRed, BrickRed, 1)
w = _Width(One): h = _Height(One)

'Demo Shifting

DisplayImage Cliff, 200, 400, 1, 1, 0, 1
For i = 0 To 6: DisplayImage Zero, 200 + w * i, 400 - h, 1, 1, 0, 1: Next
DisplayImage One, 200 + w * i, 400 - h, 1, 1, 0, 1
PCopy 0, 1
Color SkyBlue
_PrintString (10, 100), "First, let's show how bit sifting works."
_Delay Delay
PCopy 1, 0
_Font f
_PrintString (250, 100), "SHIFT!"
_Font f1
_Delay 1
Cls
DisplayImage Cliff, 200, 400, 1, 1, 0, 1
For i = 0 To 5: DisplayImage Zero, 200 + w * i, 400 - h, 1, 1, 0, 1: Next
DisplayImage One, 200 + w * i, 400 - h, 1, 1, 0, 1
PCopy 0, 1
_PrintString (10, 100), "See how everything shifted left once?"
_Delay Delay
PCopy 1, 0
_PrintString (10, 100), "Of course, bytes need 8 bits!!"
_Delay Delay
PCopy 1, 0
_PrintString (10, 100), "Fill in the blank spot with 0..."
_Delay Delay
PCopy 1, 0
DisplayImage Zero, 200 + w * i + w, 400 - h, 1, 1, 0, 1
PCopy 0, 1
_Delay Delay
_PrintString (10, 100), "And we've now shifted once..."
_Delay Delay
PCopy 1, 0
_PrintString (10, 100), "Let's continue shifting!!!"
_Delay Delay
PCopy 1, 0
DisplayImage Cliff, 200, 400, 1, 1, 0, 1

For j = 4 To -2 Step -1
    _Font f
    _PrintString (250, 100), "SHIFT!"
    _Font f1
    _Delay 1
    Cls
    DisplayImage Cliff, 200, 400, 1, 1, 0, 1
    For i = 0 To j: DisplayImage Zero, 200 + w * i, 400 - h, 1, 1, 0, 1: Next
    If j <> -2 Then DisplayImage One, 200 + w * i, 400 - h, 1, 1, 0, 1
    For i = 5 To j Step -1: DisplayImage Zero, 200 + w * (i + 2), 400 - h, 1, 1, 0, 1: Next
    _Delay Delay
Next
_PrintString (10, 100), "We've shifted everything to zero..."
_Delay Delay
Beep

rotate:

'Demo rotating
Cls
DisplayImage Cliff, 200, 400, 1, 1, 0, 1
For i = 0 To 6: DisplayImage Zero, 200 + w * i, 400 - h, 1, 1, 0, 1: Next
DisplayImage One, 200 + w * i, 400 - h, 1, 1, 0, 1
PCopy 0, 1
Color SkyBlue
_PrintString (10, 100), "Now, let's see how we rotate."
_Delay Delay
PCopy 1, 0
_Font f
_PrintString (250, 100), "ROTATE!"
_Font f1
_Delay 1
Cls
DisplayImage Cliff, 200, 400, 1, 1, 0, 1
For i = 1 To 6: DisplayImage Zero, 200 + w * i, 400 - h, 1, 1, 0, 1: Next
DisplayImage One, 200 + w * i, 400 - h, 1, 1, 0, 1
PCopy 0, 1
For j = 0 To 100
    PCopy 1, 0
    DisplayImage Zero, 200, 400 - h - j, 1, 1, 0, 1
    _Delay .01
Next
_PrintString (10, 100), "Save the leftmost number."
_Delay Delay
Cls
_PrintString (10, 100), "shift the remaining values."
DisplayImage Zero, 200, 300 - h, 1, 1, 0, 1
DisplayImage Cliff, 200, 400, 1, 1, 0, 1
For j = 0 To w
    Line (200, 400 - h)-Step(w * 8, h), Black, BF 'erase our old numbers
    For i = 1 To 6: DisplayImage Zero, 200 + w * i - j, 400 - h, 1, 1, 0, 1: Next
    DisplayImage One, 200 + w * i - j, 400 - h, 1, 1, 0, 1
    _Delay .01
Next

_Delay Delay
Cls
_PrintString (10, 100), "move that saved number."
DisplayImage Cliff, 200, 400, 1, 1, 0, 1
For i = 1 To 6: DisplayImage Zero, 200 + w * i - w, 400 - h, 1, 1, 0, 1: Next
DisplayImage One, 200 + w * i - w, 400 - h, 1, 1, 0, 1
For j = 0 To w * 7
    Line (200, 300 - h)-Step(w * 8, 99), Black, BF 'erase our old numbers
    DisplayImage Zero, 200 + j, 300 - h, 1, 1, 0, 1
    _Delay .01
Next
For j = 0 To 99
    Line (200 + w * 7, 300 - h + j)-Step(w, 99), Black, BF 'erase our old numbers
    DisplayImage Zero, 200 + w * 7, 300 - h + j, 1, 1, 0, 1
    _Delay .01
Next
Line (10, 100)-(1900, 200), Black, BF
PCopy 0, 1
_PrintString (10, 100), "Notice that rotation at work?"
_Delay Delay
PCopy 1, 0
_PrintString (10, 100), "Let's continue rotating!!!"
_Delay Delay
PCopy 1, 0
DisplayImage Cliff, 200, 400, 1, 1, 0, 1

For j = 4 To -1 Step -1
    _Font f
    _PrintString (250, 100), "ROTATE!"
    _Font f1
    _Delay 1
    Cls
    DisplayImage Cliff, 200, 400, 1, 1, 0, 1
    For i = 0 To j: DisplayImage Zero, 200 + w * i, 400 - h, 1, 1, 0, 1: Next
    If j <> -2 Then DisplayImage One, 200 + w * i, 400 - h, 1, 1, 0, 1
    For i = 5 To j Step -1: DisplayImage Zero, 200 + w * (i + 2), 400 - h, 1, 1, 0, 1: Next
    _Delay Delay
Next
_Font f
_PrintString (250, 100), "ROTATE!"
_Font f1
_Delay 1
Cls
DisplayImage Cliff, 200, 400, 1, 1, 0, 1
For i = 0 To 6: DisplayImage Zero, 200 + w * i, 400 - h, 1, 1, 0, 1: Next
DisplayImage One, 200 + w * i, 400 - h, 1, 1, 0, 1
_Delay Delay
_PrintString (10, 100), "We've rotated back to start!!"
_Delay Delay
Cls
Print "See the difference?"
Print "One shifts the bits."
Print "One rotates the bits."
Print
Print "That's all there is to it!"
Color White
End

Function TextToImage& (text$, font&, fc&, bfc&, mode As _Byte)
    'text$ is the text that we wish to transform into an image.
    'font& is the handle of the font we want to use.
    'fc& is the color of the font we want to use.
    'bfc& is the background color of the font.

    'Mode 1 is print forwards
    'Mode 2 is print backwards
    'Mode 3 is print from top to bottom
    'Mode 4 is print from bottom up
    'Mode 0 got lost somewhere, but it's OK.  We check to see if our mode is < 1 or > 4 and compensate automatically if it is to make it one (default).

    If mode < 1 Or mode > 4 Then mode = 1
    dc& = _DefaultColor: bgc& = _BackgroundColor
    D = _Dest
    F = _Font
    T2Idown = CsrLin: T2Iright = Pos(0)
    If font& <> 0 Then _Font font&
    If mode < 3 Then
        'print the text lengthwise
        w& = _PrintWidth(text$): h& = _FontHeight
    Else
        'print the text vertically
        For i = 1 To Len(text$)
            If w& < _PrintWidth(Mid$(text$, i, 1)) Then w& = _PrintWidth(Mid$(text$, i, 1))
        Next
        h& = _FontHeight * (Len(text$))
    End If

    TextToImage_temp& = _NewImage(w&, h&, 32)
    TextToImage = TextToImage_temp&
    _Dest TextToImage_temp&
    If font& <> 0 Then _Font font&
    Color fc&, bfc&

    Select Case mode
        Case 1
            'Print text forward
            _PrintString (0, 0), text$
        Case 2
            'Print text backwards
            temp$ = ""
            For i = 0 To Len(text$) - 1
                temp$ = temp$ + Mid$(text$, Len(text$) - i, 1)
            Next
            _PrintString (0, 0), temp$
        Case 3
            'Print text upwards
            'first lets reverse the text, so it's easy to place
            temp$ = ""
            For i = 0 To Len(text$) - 1
                temp$ = temp$ + Mid$(text$, Len(text$) - i, 1)
            Next
            'then put it where it belongs
            For i = 1 To Len(text$)
                fx = (w& - _PrintWidth(Mid$(temp$, i, 1))) / 2 + .99 'This is to center any non-monospaced letters so they look better
                _PrintString (fx, _FontHeight * (i - 1)), Mid$(temp$, i, 1)
            Next
        Case 4
            'Print text downwards
            For i = 1 To Len(text$)
                fx = (w& - _PrintWidth(Mid$(text$, i, 1))) / 2 + .99 'This is to center any non-monospaced letters so they look better
                _PrintString (fx, _FontHeight * (i - 1)), Mid$(text$, i, 1)
            Next
    End Select
    _Dest D
    Color dc&, bgc&
    _Font F
    Locate T2Idown, T2Iright
End Function

Sub DisplayImage (Image As Long, x As Integer, y As Integer, xscale As Single, yscale As Single, angle As Single, mode As _Byte)
    'Image is the image handle which we use to reference our image.
    'x,y is the X/Y coordinates where we want the image to be at on the screen.
    'angle is the angle which we wish to rotate the image.
    'mode determines HOW we place the image at point X,Y.
    'Mode 0 we center the image at point X,Y
    'Mode 1 we place the Top Left corner of oour image at point X,Y
    'Mode 2 is Bottom Left
    'Mode 3 is Top Right
    'Mode 4 is Bottom Right


    Dim px(3) As Integer, py(3) As Integer, w As Integer, h As Integer
    Dim sinr As Single, cosr As Single, i As _Byte
    w = _Width(Image): h = _Height(Image)
    Select Case mode
        Case 0 'center
            px(0) = -w \ 2: py(0) = -h \ 2: px(3) = w \ 2: py(3) = -h \ 2
            px(1) = -w \ 2: py(1) = h \ 2: px(2) = w \ 2: py(2) = h \ 2
        Case 1 'top left
            px(0) = 0: py(0) = 0: px(3) = w: py(3) = 0
            px(1) = 0: py(1) = h: px(2) = w: py(2) = h
        Case 2 'bottom left
            px(0) = 0: py(0) = -h: px(3) = w: py(3) = -h
            px(1) = 0: py(1) = 0: px(2) = w: py(2) = 0
        Case 3 'top right
            px(0) = -w: py(0) = 0: px(3) = 0: py(3) = 0
            px(1) = -w: py(1) = h: px(2) = 0: py(2) = h
        Case 4 'bottom right
            px(0) = -w: py(0) = -h: px(3) = 0: py(3) = -h
            px(1) = -w: py(1) = 0: px(2) = 0: py(2) = 0
    End Select
    sinr = Sin(angle / 57.2957795131): cosr = Cos(angle / 57.2957795131)
    For i = 0 To 3
        x2 = xscale * (px(i) * cosr + sinr * py(i)) + x: y2 = yscale * (py(i) * cosr - px(i) * sinr) + y
        px(i) = x2: py(i) = y2
    Next
    _MapTriangle (0, 0)-(0, h - 1)-(w - 1, h - 1), Image To(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
    _MapTriangle (0, 0)-(w - 1, 0)-(w - 1, h - 1), Image To(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
End Sub
Reply
#2
If we're not careful, the IDE will eventually become a full blown Assembler. Wink
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
Reply
#3
(09-05-2022, 11:22 PM)SMcNeill Wrote: Folks seem to be asking, "What's _ROL and _ROR?  How are the different from the bit shifting routines for _SHL and _SHR?"
Simple answer:

Shift is like a bulldozer pushing the bits off the edge. The bits are replaced by 0 for non-negative numbers and 1 for negative numbers.

Rotate is like putting the bits on a conveyor belt or a lazy Susan. the bits that roll off come back around.
While 1
   Fix Bugs
   report all bugs fixed
   receive bug report
end while
Reply
#4
(09-08-2022, 10:47 PM)TDarcos Wrote: Shift is like a bulldozer pushing the bits off the edge. The bits are replaced by 0 for non-negative numbers and 1 for negative numbers.

Rotate is like putting the bits on a conveyor belt or a lazy Susan. the bits that roll off come back around.

That's a great clarification that I either missed or wasn't stated elsewhere. A right shifted negative number will end at -1, the Most Significant Bits (MSB) being filled by 1s. I'll have to play with the action for _UNSIGNED types when I have more time.

Code: (Select All)
a% = -20
PRINT _BIN$(a%), a%
a% = _SHR(a%, 2)
PRINT _BIN$(a%), a%
a% = _SHR(a%, 2)
PRINT _BIN$(a%), a%
a% = _SHR(a%, 2)
PRINT _BIN$(a%), a%
a% = _SHR(a%, 2)
PRINT _BIN$(a%), a%
a% = _SHR(a%, 2)
PRINT _BIN$(a%), a%
a% = _SHR(a%, 2)
PRINT _BIN$(a%), a%
a% = _SHR(a%, 2)
PRINT _BIN$(a%), a%

I also note that with a negative value, it will put the 1s on the MSB and 0s on the LSB, depending on the shift direction. Which keeps the action working as a multiple of 2, regardless of the shift direction. Enough left shifts of a negative will, however, overflow the variable type container to 0.

Code: (Select All)
a% = -1
PRINT _BIN$(a%), a%
a% = _SHL(a%, 2)
PRINT _BIN$(a%), a%
a% = _SHL(a%, 2)
PRINT _BIN$(a%), a%
a% = _SHL(a%, 2)
PRINT _BIN$(a%), a%
a% = _SHL(a%, 2)
PRINT _BIN$(a%), a%
a% = _SHL(a%, 2)
PRINT _BIN$(a%), a%
a% = _SHL(a%, 2)
PRINT _BIN$(a%), a%
a% = _SHL(a%, 2)
PRINT _BIN$(a%), a%
a% = _SHL(a%, 2)
PRINT _BIN$(a%), a%
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
Reply




Users browsing this thread: 3 Guest(s)