Jump to content

IS this by design?


Recommended Posts

Hello all.  I have noticed that the Int conversion function behaves in a manner that I would not expect to be by design, and I wanted to confirm if it was, in fact, by design.  Lets consider the below line of code:

Int ("This is not an integer")

Now, in other scripting languages, like powershell, if you try converting a string like the one above into an integer, it throws an error:

maVSAXJ.png

I would expect autoit would behave in a similar way.  However, when you run the sample at the beginning of the post, it does not return an error.  It actually successfully returns the integer 0, which is a very odd behavior, since that would seem to indicate that the integers Int ("0" ) and Int ("Any string which is not an integer" ) are equal and valid.  Consider the below script, in which I used Mediainfo.dll to return the properties associated with a media file on my computer.  To make it more easy to follow along, the contents of the $array variable will be displayed underneath the code snippet:

For $i = 0 To UBound ( $Array ) - 1 Step 1
    $split = StringSplit ( StringStripWS ( $Array[$i], 8 ), ":", 2 ) ;We try to split each line using ":" as the delimeter
    If @error Then ;set error variable to 0 and continueloop if split fails
        SetError ( 0 )
        ContinueLoop
    EndIf
    If StringLeft ( $split[0], 5 ) = "Width" And IsInt ( Int ( $split[1] ) ) Then ;looking for the line "Width:1208" (spaces removed for convenience) in the array/text file
        $width = $split[1]
    EndIf
    If StringLeft ( $split[0], 6 ) = "Height" And IsInt ( Int ( $split[1] ) ) Then ;looking for the line "Height:807" (spaces removed for convenience) in the array/text file
        $height = $split[1]
    EndIf

Next

The contents of $array varialbe:

General

Count                                    : 331

Count of stream of this kind             : 1

Kind of stream                           : General

Kind of stream                           : General

Stream identifier                        : 0

Count of image streams                   : 1

Image_Format_List                        : PNG

Image_Format_WithHint_List               : PNG

Codecs Image                             : PNG

Complete name                            : C:\Users\whiggs\Pictures\2018-03-22 15_00_45-ASUS Wireless Router RT-AC1750 - Network Map.png

Folder name                              : C:\Users\whiggs\Pictures

File name extension                      : 2018-03-22 15_00_45-ASUS Wireless Router RT-AC1750 - Network Map.png

File name                                : 2018-03-22 15_00_45-ASUS Wireless Router RT-AC1750 - Network Map

File extension                           : png

Format                                   : PNG

Format                                   : PNG

Format/Info                              : Portable Network Graphic

Format/Extensions usually used           : png pns

Commercial name                          : PNG

Internet media type                      : image/png

File size                                : 186290

File size                                : 182 KiB

File size                                : 182 KiB

File size                                : 182 KiB

File size                                : 182 KiB

File size                                : 181.9 KiB

Stream size                              : 0

Stream size                              : 0.00 Byte (0%)

Stream size                              :  Byte0

Stream size                              : 0.0 Byte

Stream size                              : 0.00 Byte

Stream size                              : 0.000 Byte

Stream size                              : 0.00 Byte (0%)

Proportion of this stream                : 0.00000

File creation date                       : UTC 2020-03-29 21:56:57.140

File creation date (local)               : 2020-03-29 17:56:57.140

File last modification date              : UTC 2018-03-22 19:00:52.860

File last modification date (local)      : 2018-03-22 15:00:52.860



Image

Count                                    : 124

Count of stream of this kind             : 1

Kind of stream                           : Image

Kind of stream                           : Image

Stream identifier                        : 0

Format                                   : PNG

Format                                   : PNG

Format/Info                              : Portable Network Graphic

Commercial name                          : PNG

Format_Compression                       : LZ77

Internet media type                      : image/png

Width                                    : 1208

Width                                    : 1 208 pixels

Height                                   : 807

Height                                   : 807 pixels

Bit depth                                : 32

Bit depth                                : 32 bits

Compression mode                         : Lossless

Compression mode                         : Lossless

Stream size                              : 186290

Stream size                              : 182 KiB (100%)

Stream size                              : 182 KiB

Stream size                              : 182 KiB

Stream size                              : 182 KiB

Stream size                              : 181.9 KiB

Stream size                              : 182 KiB (100%)

Proportion of this stream                : 1.00000

Unfortunately, Autoit reads in the text as a string, so trying to use IsInt ($split[1]) fails to identify the value "1208" as an int when passed the line containing the text we are looking for because it is a string in this context.  So, my first thought as to how to solve this would be to attempt to convert the string into an integer before passing it to "isInt ()", and use error handling to handle instances where an actual string is passed to Int().  However, that logic does not work with autoit because the Int() conversion function, even when passed what should be invalid parameter, still returns a variable as if it had processed successfully: 0.  0 is an int, and "0" does not equal "This is not an integer".  It just seems really odd that Autoit's Int() conversion function takes what should be and invalid parameter entry and returns a valid integer value.  Just to be clear here, I am not asking for help.  I already was able to work around this using regular expressions instead.  I am simply asking if this kind of behavior in Autoit is by design.  That is all.

 

Edited by MattHiggs
Link to comment
Share on other sites

  • Developers

A bit of a long story to ask about the int() & IsInt() functions.
AutoIt3's Int() function converts the expression found into a integer, and doesn't cast like I assume your screen capture example does.
Int("whatever string") will result in an integer value containing 0 , so IsInt(Int("whatever string") )  obviously will always be true!
You need to test the original expression with IsInt() to get a result you want. So in simple script form:

Dim $split[2] = [1, "test"]
ConsoleWrite("$split[1]=" & $split[1] & @CRLF)
ConsoleWrite("Int($split[1])=" & Int($split[1]) & @CRLF)
ConsoleWrite("incorrect test IsInt(Int($split[1]))=" & IsInt(Int($split[1])) & @CRLF)
ConsoleWrite("correct test   IsInt($split[1])=" & IsInt($split[1]) & @CRLF)

Jos

 

Edited by Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

@Jos Your logic is right, but I think OP is wanting to know why Int doesn't have a error-checking mechanism to detect non-numeric input.

@MattHiggs It does look like this function works this way by design, I do agree that it would be nice to have some error-checking mechanism, the best way to implement it would be to set @error in case the input is not numeric, this is backward compatible with existing code :)

I guess this is something I can implement in my cross-platform implementation :D

Edited by TheDcoder

EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time)

DcodingTheWeb Forum - Follow for updates and Join for discussion

Link to comment
Share on other sites

  • Developers
2 minutes ago, TheDcoder said:

@Jos Your logic is right, but I think OP is wanting to know why Int doesn't have a error-checking mechanism to detect non-numeric input.

I don't understand that question. It simply converts any none numeric to 0 as AutoIt3 always does without setting any @error flag.

Edited by Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

2 minutes ago, Jos said:

I don't understand that question.

I think you are mis-understanding the question, OP is aware of how the function works, but he wants to know why it was designed to work that way.

EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time)

DcodingTheWeb Forum - Follow for updates and Join for discussion

Link to comment
Share on other sites

  • Developers

This could be an approach to test a variable whether it contains an INT, either as number or string:

_TestInt("1028")
_TestInt(1028)
_TestInt(1028.5)
_TestInt("1028.5")
_TestInt("test")

Func _TestInt($istr)
    If _IsInt($istr) Then
        ConsoleWrite($istr & " is INT" & @CRLF)
    Else
        ConsoleWrite($istr & " is not an INT" & @CRLF)
    EndIf
EndFunc

; Test whether the variable contains an INT value either as string of number
Func _IsInt($istr)
    Return $istr == Int($istr)
EndFunc   ;==>_IsInt

Jos

Edited by Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

@MattHiggs
As Jos suggested, you could build your own "IsInt" function, like the following one:

#include <StringConstants.au3>

Global $blnReturnValue

$blnReturnValue = (_IsInt(10)     = 1 ? ConsoleWrite("Is Integer!" & @CRLF) : ConsoleWrite("Is NOT an Integer! Error: " & @error & @CRLF))
$blnReturnValue = (_IsInt(+15)    = 1 ? ConsoleWrite("Is Integer!" & @CRLF) : ConsoleWrite("Is NOT an Integer! Error: " & @error & @CRLF))
$blnReturnValue = (_IsInt(-20)    = 1 ? ConsoleWrite("Is Integer!" & @CRLF) : ConsoleWrite("Is NOT an Integer! Error: " & @error & @CRLF))
$blnReturnValue = (_IsInt("ABCD") = 1 ? ConsoleWrite("Is Integer!" & @CRLF) : ConsoleWrite("Is NOT an Integer! Error: " & @error & @CRLF))
$blnReturnValue = (_IsInt(150.2)  = 1 ? ConsoleWrite("Is Integer!" & @CRLF) : ConsoleWrite("Is NOT an Integer! Error: " & @error & @CRLF))
$blnReturnValue = (_IsInt(-19.0)  = 1 ? ConsoleWrite("Is Integer!" & @CRLF) : ConsoleWrite("Is NOT an Integer! Error: " & @error & @CRLF))
$blnReturnValue = (_IsInt(2430)   = 1 ? ConsoleWrite("Is Integer!" & @CRLF) : ConsoleWrite("Is NOT an Integer! Error: " & @error & @CRLF))
$blnReturnValue = (_IsInt("")     = 1 ? ConsoleWrite("Is Integer!" & @CRLF) : ConsoleWrite("Is NOT an Integer! Error: " & @error & @CRLF))


Func _IsInt($varUserInput)
    Return (StringRegExp($varUserInput, '^(?:[-+])?\d+(?:\.0)?$', $STR_REGEXPMATCH) = True ? SetError(0, 0, 1) : SetError(-1, 0, 0))
EndFunc

:)

Edited by FrancescoDiMuro

Click here to see my signature:

Spoiler

ALWAYS GOOD TO READ:

 

Link to comment
Share on other sites

@Jos Nice! I was thinking if it was possible to write an UDF without using manual checking or RegEx but did not think of comparing the string with the number :)

@FrancescoDiMuro He is already using RegEx according to his first post.

EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time)

DcodingTheWeb Forum - Follow for updates and Join for discussion

Link to comment
Share on other sites

@FrancescoDiMuro I only wanted to point out that OP was already using regex, but thanks for sharing the RegEx version :)

EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time)

DcodingTheWeb Forum - Follow for updates and Join for discussion

Link to comment
Share on other sites

Ahem! ... An integer may be signed and "1.0" is converted to an integer (not a double).

So back to drawing board for both == and regex guys!

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

  • Developers
6 minutes ago, jchd said:

Ahem! ... An integer may be signed and "1.0" is converted to an integer (not a double).

The sign I agree that the + needs to be removed in the string before compare, but the "1.0" should be _IsInt("1.0") = False ...right?

Jos  

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

1 hour ago, Jos said:

Design choices is one Jon would have to answer.

This is probably neither the right place nor the right time (if it even exists) to ask this blasphemous question, but is @Jon  really the only one who can make adjustments (at least minor ones)  in the AutoIt core? 

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

Link to comment
Share on other sites

Local $aInts =["1", "1.00", "1e0", "1e2", "1e-0", "1e+2", "1000000000000000000000000000000000000000000", "1000000000000000000000000000000000000000000.0", "1e120"]

For $s In $aInts
    ConsoleWrite($s & @TAB & IsInt(Number($s)) & @TAB & VarGetType(Number($s)) & @TAB & Number($s) & @LF)
    ConsoleWrite("+" & $s & @TAB & IsInt(Number($s)) & @TAB & VarGetType(Number($s)) & @TAB & Number("+" & $s) & @LF)
    ConsoleWrite("-" & $s & @TAB & IsInt(Number($s)) & @TAB & VarGetType(Number($s)) & @TAB & Number("-" & $s) & @LF)
Next

; That's the unnoticed bug AFAIK
ConsoleWrite(Number("12345678901234567890") & @LF)

More surprises when you look closer!

Edited by jchd
Sorry for so many edits!

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

  • Developers

Just trying to understand what you are showing with this example:
What is the difference between the last 2 consolewrite's other than then the starting character? 

 

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

This shows all the forms that a string can check the IsInt() test. Note the changed version and the underlying bugs in some conversions.

I just realized that "1E3" is not recognized as an integer FP value while "1e3" is.

Edited by jchd

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

Last test version with fixed version of Number()

Local $aInts =["", "1", "00001", "1.00", "1e0", "001.e0", "1e-0", "1e2", "1.0e+2", "9223372036854775807", "9223372036854775808", "10000000000000000000", "1000000000000000000.0", "1e120"]

For $s In $aInts
    ConsoleWrite($s & @TAB & IsInt(Number($s)) & @TAB & VarGetType(Number($s)) & @TAB & Number($s) & @TAB & "==>" & @TAB & VarGetType(_Number($s)) & @TAB & _Number($s) & @LF)
    ConsoleWrite("+" & $s & @TAB & IsInt(Number($s)) & @TAB & VarGetType(Number($s)) & @TAB & Number("+" & $s) & @TAB & "==>" & @TAB & VarGetType(_Number("+" & $s)) & @TAB & _Number("+" & $s) & @LF)
    ConsoleWrite("-" & $s & @TAB & IsInt(Number($s)) & @TAB & VarGetType(Number($s)) & @TAB & Number("-" & $s) & @TAB & "==>" & @TAB & VarGetType(_Number("-" & $s)) & @TAB & _Number("-" & $s) & @LF & @LF)
Next

; That's the unnoticed bug AFAIK
ConsoleWrite("33333333333333333333 gets erroneously converted to MaxInt64 = " & Number("33333333333333333333") & @LF & @LF)

; fixed version of Number()
Func _Number($s)
    Local $a = StringRegExp($s, "^([-+]?)0*(\d+)$", 1)
    If Not @error Then
        Local $l = StringLen($a[1])
        ; in case the int is oversized
        If $l > 19 Or ($a[0] <> "-" And $a[1] > "9223372036854775807") Or ($a[0] = "-" And $a[1] > "9223372036854775808") Then Return Number($s & ".0")
    EndIf
    Return Number($s)
EndFunc

Again sorry for multiple edits but I kept discovering missing cases.

I regard the current behavior of Number($s) as buggy when it silently converts input outside the Int64 range to MaxInt64 or MinInt64.

Also the exemple in help is missing the minus sign:

Local $dNumber13 = Number("-30") ; Returns 30

 

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

Thanks for all the comments, guys.  I did not expect this much discussion on the matter.  Lol.  So, short answer is that, yes, it is by design.  That is all I needed to know.  Thanks!!

Edited by MattHiggs
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...