Announcement

Collapse
No announcement yet.

Reading string byte into signed variable

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Reading string byte into signed variable

    Is there a more simple way to read a string byte value into a signed variable?
    I now use this (I find it a bit of a kludge):

    Code:
          TempInt = Asc(Mid$(lBuff,Cnt,1))                                                    
          Shift Left TempInt,8
          Shift Signed Right TempInt,8
    I need it to set value of an up-down control that can vary between -50 and +50
    Regards,
    Peter

  • #2
    "... more simple ..." will be in your opinion. I'll just say different.
    Code:
    TempInt = mak(integer, 0, asc(mid$(lBuff, Cnt, 1)) 'already at left, no need shift left
    shift signed right TempInt, 8
    Or a UDT var with a low byte and a high byte, in a UNION with an INTEGER. Or, use byte pointers to get character value and put in upper byte of integer (to eliminate shift left. you'll still need the shift signed right to leave a potential sign bit in place.

    If you want one of these "fleshed out" just ask.

    Cheers,
    Dale

    Comment


    • #3
      Thanks,

      Still a pity PB lacks signed bytes...
      Regards,
      Peter

      Comment


      • #4
        Additional - For an actual negative integer, you'll have to also convert the value to two's compliment if sign bit set. Something like clear MSB then times -1.

        Cheers,
        Dale

        Comment


        • #5
          Originally posted by Peter Lameijn View Post
          Thanks,

          Still a pity PB lacks signed bytes...
          See bit variables in Help for TYPE/END TYPE. Something like MyByte as BIT * 7 IN BYTE, Sign as SBIT * 1
          (of course I don't know about doing arithmatic with them)


          Cheers,
          Dale

          Comment


          • #6
            The values in the string are already signed; it's just a problem transferring them to PB...
            Regards,
            Peter

            Comment


            • #7
              How about setting the byte value between 50 and 150 and letting TempInt=100-Asc(Mid$(lBuff,Cnt,1))

              Comment


              • #8
                Then MAK() and SHIFT SIGNED RIGHT, nothing else needed.
                Dale

                Comment


                • #9
                  MID$ slows it down. Try TempInt = ASC(lBuff, Cnt)

                  Comment


                  • #10
                    What if not first or last byte in multi byte string? No MID$ means something (like) pointers to get any byte

                    added - ((Borje's ok as is. I had to go look up second param of ASC() ))
                    Last edited by Dale Yarker; 4 Oct 2018, 01:13 PM.
                    Dale

                    Comment


                    • #11
                      One way...
                      Code:
                      SignedInt = ASC(sBuffer, Offset) - IIF(ASC(sBuffer, Offset) > 127, 256, 0)

                      Comment


                      • #12
                        Easy.

                        A byte holds a value of 0 to 255. If the values going in are always -50 to 50, simply add 50 to the value and store it in a byte. When you get it out get the byte value (0 to 100) and always subtract 50.

                        You are then treating the byte value as simply an offset from -50.

                        No bit shifting required. The key is to always make sure the original value is within the range allowed of -50 to 50. If you want the max possible values from a byte, then allow a range from -127 to 127 and add 127 to the original value and store it as a byte and then when you get it out simply subtract 127. You can define any range you want.

                        Chris Boss
                        Computer Workshop
                        Developer of "EZGUI"
                        http://cwsof.com
                        http://twitter.com/EZGUIProGuy

                        Comment


                        • #13
                          The thougth crossed my mind to do so, but would like to keep it generic if possible.
                          (easier if client in future wants to change the range of the control)
                          Dale's solution already saves me a line...

                          Another question I ran across with the up-down control:
                          Is it possible to set a stepsize for it? (I mean step 5: 0-5-10-15-20...)
                          Regards,
                          Peter

                          Comment


                          • #14
                            Quicker, but maybe not simpler:
                            Code:
                            'PBCC6 program
                            FUNCTION PBMAIN AS LONG
                            
                            #REGISTER NONE       '####### needed to make sure TempInt isn't made a register variable
                            LOCAL lBuff AS STRING
                            LOCAL Cnt AS LONG
                            'LOCAL TempInt AS LONG
                            LOCAL TempInt AS INTEGER
                            
                            
                            lBuff = CHR$(128)       'signed -128
                            lBuff = lBuff + CHR$(129)   'signed -127
                            lBuff = lBuff + CHR$(127)   'signed 127
                            lBuff = lBuff + CHR$(255)   'signed -1
                            lBuff = lBuff + CHR$(0)     'signed 0
                            lBuff = lBuff + CHR$(42)   'signed 42
                            
                            
                            FOR cnt = 1 TO LEN(lBuff)
                            
                                    TempInt = ASC(MID$(lBuff,Cnt,1))
                                    !movsx ax,byte ptr TempInt      'mov and sign extend the byte at TempInt into the AX register
                                    !mov TempInt,ax                 'move the new sign extended value back to TempInt
                            
                                    PRINT TempInt
                            
                            
                                    TempInt = ASC(MID$(lBuff,Cnt,1))
                                    SHIFT LEFT TempInt,8
                                    SHIFT SIGNED RIGHT TempInt,8
                            
                                    PRINT TempInt
                                    PRINT
                            
                            NEXT
                            
                            WAITKEY$
                            
                            END FUNCTION

                            Comment


                            • #15
                              Is it possible to set a stepsize for it? (I mean step 5: 0-5-10-15-20...)

                              You may easily cheat using UDM_SETACCEL.

                              Code:
                              LOCAL UdAcc AS UDACCEL : UdAcc.nInc = 5 : UdAcc.nSec = 0
                              SendDlgItemMessage(hDlg, %IDC_UPDOWN1, %UDM_SETACCEL, 1, VARPTR(UdAcc))
                              Last edited by Pierre Bellisle; 5 Oct 2018, 09:52 AM.

                              Comment


                              • #16
                                Can trap %UDN_DELTAPOS notification and alter value there. Small example:
                                Code:
                                '====================================================================
                                ' Declares
                                '--------------------------------------------------------------------
                                #COMPILE EXE
                                '------------------------------------------------
                                #INCLUDE "WIN32API.INC"
                                %IDC_TEXTBOX1 = 121
                                %IDC_UPDOWN1  = 201
                                
                                
                                '====================================================================
                                ' Program entrance
                                '--------------------------------------------------------------------
                                FUNCTION PBMAIN () AS LONG
                                  LOCAL hDlg AS DWORD
                                
                                  DIALOG NEW 0, "UpDown step test",,, 220, 140, %WS_CAPTION OR %WS_SYSMENU, 0 TO hDlg
                                
                                  '------------------------------------------------------------------
                                  InitCommonControls
                                  CONTROL ADD TEXTBOX, hDlg, %IDC_TEXTBOX1, "0", 5, 5, 45, 12, _
                                        %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %ES_NUMBER, %WS_EX_CLIENTEDGE
                                
                                  CONTROL ADD "msctls_updown32", hDlg, %IDC_UPDOWN1, "", 0, 0, 8, 8, _
                                        %WS_CHILD OR %WS_VISIBLE OR %UDS_ARROWKEYS OR %UDS_SETBUDDYINT OR _
                                        %UDS_ALIGNRIGHT OR %UDS_AUTOBUDDY
                                
                                  CONTROL SEND hDlg, %IDC_UPDOWN1, %UDM_SETBUDDY, GetDlgItem(hDlg, %IDC_TEXTBOX1), 0
                                  CONTROL SEND hDlg, %IDC_UPDOWN1, %UDM_SETRANGE, 0&, MAK(LONG, 50, -50)
                                
                                  '------------------------------------------------------------------
                                  DIALOG SHOW MODAL hDlg CALL DlgProc
                                
                                END FUNCTION
                                
                                
                                '====================================================================
                                ' Main Dialog procedure
                                '--------------------------------------------------------------------
                                CALLBACK FUNCTION DlgProc() AS LONG
                                  LOCAL pNM_UD AS NM_UPDOWN PTR
                                
                                  SELECT CASE AS LONG CB.MSG
                                
                                  CASE %WM_NOTIFY
                                      pNM_UD = CB.LPARAM
                                      IF @pNM_UD.hdr.idFrom = %IDC_UPDOWN1 AND _
                                          @pNM_UD.hdr.code = %UDN_DELTAPOS THEN
                                
                                          IF @pNM_UD.iDelta = 1 THEN  ' positive direction, else negative
                                              @pNM_UD.iPos += 4  ' set new value 5, 10, etc..
                                          ELSE
                                              @pNM_UD.iPos -= 4  ' set new value -5,-10, etc
                                          END IF
                                          CONTROL SEND CB.HNDL, %IDC_UPDOWN1, %UDM_SETPOS, 0, @pNM_UD.iPos ' set new value
                                      END IF
                                
                                  END SELECT
                                END FUNCTION

                                Comment


                                • #17
                                  Thanks,

                                  I now use the WM_HSCROLL to update the shown value, works fine also...
                                  Some docs state that the (set)buddy control is mandatory, is that correct?
                                  (I don't need it, and updown seems to work fine without)

                                  Code:
                                      Case %WM_HScroll               
                                        CONTROL SEND hDlg, GetDlgCtrlID(CblParam), %UDM_GETPOS, 0, 0 to lRet
                                        lRetI = lRet
                                        Dialog Set Text hDlg, Format$(GetDlgCtrlID( Cblparam)) + ", Hor) - " + Format$(lRetI *5)
                                  Regards,
                                  Peter

                                  Comment

                                  Working...
                                  X