Jump to content

Function hex gives incorrect results


Recommended Posts

Hi,

The following demo code illustrates the issue I am running into:

$m_nTemp = InputBox("Bang", "Enter number", "" )
$m_nTemp = $m_nTemp * 2
;$m_nTemp = number( $m_nTemp )
;$m_nTemp = string( $m_nTemp )
ConsoleWrite( "variable type: " & _VarDump( $m_nTemp ) & @CRLF )    
ConsoleWrite("test1: " & $m_nTemp & " : "& hex( $m_nTemp, 2 ) & @CRLF )
$m_nTemp = 4
ConsoleWrite( "variable type: " & _VarDump( $m_nTemp ) & @CRLF )
ConsoleWrite("test2: " & $m_nTemp & " : "& hex( $m_nTemp, 2 ) & @CRLF )

Func _VarDump(ByRef $vVar, $sIndent = '', $IsSupposedToBeUnknown = False)
Select
     Case $IsSupposedToBeUnknown
         Return 'Unknown(' & $vVar & ')'
     Case IsDllStruct($vVar)
         Return 'Struct(' & DllStructGetSize($vVar) & ')'
     Case IsArray($vVar)
         Return 'Array' & @CRLF & _VarDumpArray($vVar, $sIndent)
     Case IsBinary($vVar)
         Return 'Binary(' & BinaryLen($vVar) & ')'
     Case IsBool($vVar)
         Return 'Boolean(' & $vVar & ')'
     Case IsFloat($vVar)
         Return 'Float(' & $vVar & ')'
     Case IsHWnd($vVar)
         Return 'HWnd(' & $vVar & ')'
     Case IsInt($vVar)
         Return 'Integer(' & $vVar & ')'
     Case IsKeyword($vVar)
         Return 'Keyword(' & $vVar & ')'
     Case IsObj($vVar)
         Return 'Object(' & ObjName($vVar) & ')'
     Case IsString($vVar)
         Return 'String(' & StringLen($vVar) & ') ' & $vVar
     Case Else
         Return 'Unknown(' & $vVar & ')'
EndSelect
EndFunc

In this state, the output is (if I enter 2 as a number):

variable type: Integer(4)

test1: 4 : 00

variable type: Integer(4)

test2: 4 : 04

If I uncomment the $m_nTemp = number( $m_nTemp ) line, then I have the same output.

If I uncomment the $m_nTemp = string( $m_nTemp ) line, then the output becomes correct (which is what you would not expect as the documentation specifies that the input should be an integer or binary type):

variable type: String(1) 4

test1: 4 : 04

variable type: Integer(4)

test2: 4 : 04

So this seems to be a bug in hex ?

Autoit v3.3.8.1

Edited by Beamer145
Link to comment
Share on other sites

I'm not seeing what your question is, or complaint. Can you explain better what you're expecting and what you're getting in a clearer manner.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

  • Moderators

Beamer145,

If you intend to use as a number the return from any function which returns a string, it is always good practice to explicitly change the datatype using Number. I have been caught out many times when reading values from ini files and not getting quite what I expected. ;)

However, in this case I do see your point. Adding a couple more ConsoleWrite lines shows that AutoIt does its best to get the correct datatype for you:

$m_nTemp = InputBox("Bang", "Enter number", "")
ConsoleWrite(_VarDump($m_nTemp) & @CRLF) ; <<<<<<<<<<<<<<<<<<<< Added
$m_nTemp = $m_nTemp * 2
ConsoleWrite(_VarDump($m_nTemp) & @CRLF) ; <<<<<<<<<<<<<<<<<<<< Added

The return is:

String(1) 2
Integer(4) ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Looks to have been changed here
variable type: Integer(4)
test1: 4 : 00 ; <<<<<<<<<<<<<<<<<<<<<<<<<<<< But not here
variable type: Integer(4)
test2: 4 : 04

The datatype is set to Integer after the multiplication operation, but Hex still returns 00.

If you force the datatype as you enter the value like this (which I would consider good practice as mentioned above):

$m_nTemp = Number(InputBox("Bang", "Enter number", "")) ; <<<<<<<<<<<<<< Forced number return
ConsoleWrite(_VarDump($m_nTemp) & @CRLF)
$m_nTemp = $m_nTemp * 2
ConsoleWrite(_VarDump($m_nTemp) & @CRLF)

you get what I would expect as a return:

Integer(2)
Integer(4)
variable type: Integer(4)
test1: 4 : 04
variable type: Integer(4)
test2: 4 : 04

trancexx rewrote the function and so she is the only one who can explain what is happening "under the hood". But Hex is certainly not doing what I would expect - although doubtless my expectations will be shown to be erronous - and appears to be using the datatype from when the variable was first declared. ;)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Hi,

@M23 :

If you intend to use as a number the return from any function which returns a string, it is always good practice to explicitly change the datatype using Number. I have been caught out many times when reading values from ini files and not getting quite what I expected.

And that's the reason why untyped languages are a really bad idea :) (ducks)

But anyway, the irony is that I tried enforcing the type in the commented lines, and as I mentioned it did NOT work if I explicitly changed the type to number, but it DOES work if I change the type to string. Which should have been exactly the opposite.

;$m_nTemp = number( $m_nTemp )
;$m_nTemp = string( $m_nTemp )

I did not think that place where you enforced the type matters, but as your example illustrates clearly it does.

Change it before the multiplication and it works, change it after the multiplication and it does not help anymore.

Also funny: If after the multiplication I change it first to a string, and then to a number again then it also works.

So apparently when autoit automatically changes the type for you it does some fishy stuff, probably the real reason is not in the hex function but a bug somewhere in the internals of autoit type management.

EDIT: to make things even more interesting using int() instead of number ( ) after the multiplication also works ... I really picked the wrong function for the wrong place ;p

Edited by Beamer145
Link to comment
Share on other sites

int() and Number() covert string values that start with numeric characters to a number.

hex() converts numbers to a string representation of the number in hexadecimal format.

"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to build bigger and better idiots. So far, the universe is winning."- Rick Cook

Link to comment
Share on other sites

You can't see the forest for the trees.

The real issues aren't even mentioned here. Firstly your _VarDump doesn't give you correct results because the built-in functions you used inside return confusing results. You probably want to use VarGetType() instead of IsWhatever() if you want to "dump" the input.

Secondly, if you want to see how Hex() really works then don't limit it by passing second argument. Then you will get much clearer view on the real issues.

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

  • Moderators

trancexx,

Thanks for that hint - as I said earlier, I knew my expectations would be erronous. :(

$m_nTemp = InputBox("Bang", "Enter number", "")
ConsoleWrite($m_nTemp & " : " & VarGetType($m_nTemp) & @CRLF)
$m_nTemp = $m_nTemp * 2
ConsoleWrite($m_nTemp & " : " & VarGetType($m_nTemp) & @CRLF)

ConsoleWrite("variable type: " & VarGetType($m_nTemp) & @CRLF)
ConsoleWrite("test1: " & $m_nTemp & " : " & Hex($m_nTemp) & @CRLF)
$m_nTemp = 4
ConsoleWrite("variable type: " & VarGetType($m_nTemp) & @CRLF)
ConsoleWrite("test2: " & $m_nTemp & " : " & Hex($m_nTemp) & @CRLF)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Interesting stuff , thanks

I got the _Vardump function from which is at the time of writing the #1 google result when looking for "autoit get variable type" ( I will add a reference to this discussion in that topic).

But that function is wrong then, the IsInt function tells you if the value is an integer, but not if the type is an integer, hence the confusion because a double type can have an integer value....

This also means the documentation of IsInt (http://www.autoitscript.com/autoit3/docs/functions/IsInt.htm) is incorrect.

It states "Checks if a variable or expression is an integer TYPE.". This should become " ... is an integer VALUE."

Some code for future reference:

$m_nTemp = 0.1234
_VarDump( $m_nTemp )
$m_nTempHelper =  number($m_nTemp)
_VarDump( $m_nTempHelper  )
$m_nTempHelper = int($m_nTemp)
_VarDump( $m_nTempHelper  )
ConsoleWrite(@CRLF)
ConsoleWrite(@CRLF)
$m_nTemp = 4
_VarDump( $m_nTemp )
$m_nTempHelper =  number($m_nTemp)
_VarDump( $m_nTempHelper  )
$m_nTempHelper = int($m_nTemp)
_VarDump( $m_nTempHelper  )
ConsoleWrite(@CRLF)
ConsoleWrite(@CRLF)
$m_nTemp = InputBox("Bang", "Enter number", "")
_VarDump( $m_nTemp )
$m_nTempHelper =  number($m_nTemp)
_VarDump( $m_nTempHelper  )
$m_nTempHelper = int($m_nTemp)
_VarDump( $m_nTempHelper  )
ConsoleWrite(@CRLF)
ConsoleWrite(@CRLF)
$m_nTemp = $m_nTemp * 2
_VarDump( $m_nTemp )
$m_nTempHelper =  number($m_nTemp)
_VarDump( $m_nTempHelper  )
$m_nTempHelper = int($m_nTemp)
_VarDump( $m_nTempHelper  )

Func _VarDump(ByRef $vVar, $sIndent = '', $IsSupposedToBeUnknown = False)
ConsoleWrite("VarGetType: " & $vVar & " : " & VarGetType($vVar) & @CRLF)
Select
  Case $IsSupposedToBeUnknown
   ConsoleWrite( 'Unknown(' & $vVar & ')' & @CRLF)
  Case IsDllStruct($vVar)
   ConsoleWrite( 'Struct(' & DllStructGetSize($vVar) & ')' & @CRLF)
  ;Case IsArray($vVar)
   ;Return 'Array' & @CRLF & _VarDumpArray($vVar, $sIndent)
  Case IsBinary($vVar)
   ConsoleWrite('Binary(' & BinaryLen($vVar) & ')' & @CRLF)
  Case IsBool($vVar)
   ConsoleWrite('Boolean(' & $vVar & ')' & @CRLF)
  Case IsFloat($vVar)
   ConsoleWrite('Float(' & $vVar & ')' & @CRLF)
  Case IsHWnd($vVar)
   ConsoleWrite('HWnd(' & $vVar & ')' & @CRLF)
  Case IsInt($vVar)
   ConsoleWrite( 'Integer(' & $vVar & ')' & @CRLF)
  Case IsKeyword($vVar)
   ConsoleWrite( 'Keyword(' & $vVar & ')' & @CRLF)
  Case IsObj($vVar)
   ConsoleWrite( 'Object(' & ObjName($vVar) & ')' & @CRLF)
  Case IsString($vVar)
   ConsoleWrite( 'String(' & StringLen($vVar) & ') ' & $vVar & @CRLF)
  Case Else
   ConsoleWrite( 'Unknown(' & $vVar & ')' & @CRLF)
EndSelect
EndFunc

Output:

VarGetType: 0.1234 : Double

Float(0.1234)

VarGetType: 0.1234 : Double

Float(0.1234)

VarGetType: 0 : Int32

Integer(0)

VarGetType: 4 : Int32

Integer(4)

VarGetType: 4 : Int32

Integer(4)

VarGetType: 4 : Int32

Integer(4)

VarGetType: 2 : String

String(1) 2

VarGetType: 2 : Int32

Integer(2)

VarGetType: 2 : Int32

Integer(2)

VarGetType: 4 : Double

Integer(4)

VarGetType: 4 : Double

Integer(4)

VarGetType: 4 : Int32

Integer(4)

Link to comment
Share on other sites

You need the beta to run this one (needed for Null keyword).

Func _VarDump(ByRef $vVar, $sIndent = '')
    Local $ret, $len
    Select
        Case IsDllStruct($vVar)
            $len = DllStructGetSize($vVar)
            Local $bstruct = DllStructCreate("byte[" & $len & "]", DllStructGetPtr($vVar))
            $ret = 'Struct(' & $len & ') @:' & Hex(DllStructGetPtr($vVar)) & ' = '
            If $len <= 32 Then
                Return ($ret & DllStructGetData($bstruct, 1))
            Else
                Return ($ret & BinaryMid(DllStructGetData($bstruct, 1), 1, 16) & ' ... ' & StringTrimLeft(BinaryMid(DllStructGetData($bstruct, 1), $len - 15, 16), 2))
            EndIf
        Case IsArray($vVar)
            Local $iSubscripts = UBound($vVar, 0)
            Local $sDims = 'Array'
            $iSubscripts -= 1
            For $i = 0 To $iSubscripts
                $sDims &= '[' & UBound($vVar, $i + 1) & ']'
            Next
            Return $sDims & @CRLF & _VarDumpArray($vVar, $sIndent)
        Case IsBinary($vVar)
            $len = BinaryLen($vVar)
            $ret = 'Binary(' & BinaryLen($vVar) & ') = '
            If $len <= 32 Then
                Return ($ret & $vVar)
            Else
                Return ($ret & BinaryMid($vVar, 1, 16) & ' ... ' & StringTrimLeft(BinaryMid($vVar, $len - 15, 16), 2))
            EndIf
        Case IsBool($vVar)
            Return 'Boolean ' & $vVar
        Case IsFloat($vVar) Or (IsInt($vVar) And VarGetType($vVar) = "Double")
            Return 'Double ' & $vVar
        Case IsHWnd($vVar)
            Return 'HWnd ' & $vVar
        Case IsInt($vVar)
            Return "Integer(" & StringRight(VarGetType($vVar), 2) & ') ' & $vVar
        Case IsKeyword($vVar)
            $ret = 'Keyword '
            If $vVar = Null Then
                Return $ret & 'Null'
            Else
                Return $ret & $vVar
            EndIf
        Case IsPtr($vVar)
            Return 'Pointer @:' & StringTrimLeft($vVar, 2)
        Case IsObj($vVar)
            Return 'Object ' & ObjName($vVar)
        Case IsString($vVar)
            $len = StringLen($vVar)
            $ret = 'String(' & $len & ") "
            If StringRegExp($vVar, "[\x00-\x1F\x7F-\x9F]") Then
                If $len <= 64 Then
                    Return $ret & _DumpStringWithControlChars($vVar)
                Else
                    Return ($ret & StringMid(_DumpStringWithControlChars($vVar), 1, 32) & ' ... ' & StringTrimLeft(StringMid(_DumpStringWithControlChars($vVar), $len - 31, 32), 2))
                EndIf
            Else
                If $len <= 64 Then
                    Return $ret & "'" & $vVar & "'"
                Else
                    Return ($ret & "'" & StringMid($vVar, 1, 32) & ' ... ' & StringTrimLeft(StringMid($vVar, $len - 31, 32), 2)) & "'"
                EndIf
            EndIf
        Case Else
            Return 'Unknown ' & $vVar
    EndSelect
EndFunc   ;==>_VarDump

Func _VarDumpArray(ByRef $aArray, $sIndent = @TAB)
    Local $sDump
    Local $sArrayFetch, $sArrayRead, $bDone
    Local $iSubscripts = UBound($aArray, 0)
    Local $aUBounds[$iSubscripts]
    Local $aCounts[$iSubscripts]
    $iSubscripts -= 1
    For $i = 0 To $iSubscripts
        $aUBounds[$i] = UBound($aArray, $i + 1) - 1
        $aCounts[$i] = 0
    Next
    $sIndent &= @TAB
    While 1
        $bDone = True
        $sArrayFetch = ''
        For $i = 0 To $iSubscripts
            $sArrayFetch &= '[' & $aCounts[$i] & ']'
            If $aCounts[$i] < $aUBounds[$i] Then $bDone = False
        Next

        $sArrayRead = Execute('$aArray' & $sArrayFetch)
        If @error Then
            ExitLoop
        Else
            $sDump &= $sIndent & $sArrayFetch & ' => ' & _VarDump($sArrayRead, $sIndent)
            If Not $bDone Then
                $sDump &= @CRLF
            Else
                Return $sDump
            EndIf
        EndIf

        For $i = $iSubscripts To 0 Step -1
            $aCounts[$i] += 1
            If $aCounts[$i] > $aUBounds[$i] Then
                $aCounts[$i] = 0
            Else
                ExitLoop
            EndIf
        Next
    WEnd
EndFunc   ;==>_VarDumpArray


Func _DumpStringWithControlChars(ByRef $sStr)
    Local $sDump
    Local $aCh = StringToASCIIArray($sStr)
    Local $bInStr = False
    For $ch In $aCh
        Switch $ch
            Case 0 To 0x1F, 0x7F To 0x9F
                If $bInStr Then
                    $bInStr = False
                    $sDump &= "'"
                EndIf
                $sDump &= " 0x" & Hex($ch, 2) & " "
            Case Else
                If Not $bInStr Then
                    $bInStr = True
                    $sDump &= "'"
                EndIf
                $sDump &= ChrW($ch)
        EndSwitch
    Next
    If $bInStr Then $sDump &= "'"
    Return ($sDump)
EndFunc   ;==>_DumpStringWithControlChars

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...