Page 1 of 1

Bug: StrSplit

Posted: 03 Nov 2018, 02:42
by rodemp

Code: Select all

x:="10,15,25,991,24,25,199"
n:=[], c:=StrSplit(x, ",")
Loop c.Length()
	n[A_Index] := c[A_Index]

MsgBox n[3] "/" n[7] "`n" (n[3] > n[7]) ; 25/199 `n 1
I found that when I decomposed a string with StrSplit, some of the values were causing problems

When n[7] is between 100 and 199 it was a problem.


Testing with ahk v1 did not have this problem

Code: Select all

x:="10,15,25,991,24,25,199"
n:=[], c:=StrSplit(x, ",")
Loop % c.Length()
	n[A_Index] := c[A_Index]

MsgBox % n[3] "/" n[7] "`n" (n[3] > n[7]) ; 25/199 `n 0

Re: Bug: StrSplit  Topic is solved

Posted: 03 Nov 2018, 03:01
by jeeswg
In AHK v1, two variables containing numeric-looking strings would be compared as numbers. This has changed in AHK v2, but there was a suggestion that the AHK v1 behaviour will be brought back. (I'm trying to find the link on GitHub.) You can use +0 for the time being to convert strings to numbers.

Code: Select all

q::
var1 := "2"
var2 := "10"
;MsgBox, % var1 < var2 ;AHK v1: 1
MsgBox(var1 < var2) ;AHK v2: 0
return
[EDIT:] Here's the link:
Adding function StrCompare and disabling string compairsion of operators: < <= > >= by HelgeffegleH · Pull Request #107 · Lexikos/AutoHotkey_L · GitHub
https://github.com/Lexikos/AutoHotkey_L/pull/107
Originally I think If (a < b) performed numeric comparison if both a and b were numeric strings, so to force a string comparison one had to do something like If ("Str" a < "Str" b). In one of the alphas I changed it to perform string comparison if a and b are both strings (numeric or not), but in hindsight this was probably a bad idea. It can give contradictory results with mixed types:
I came to the same conclusion in this thread:
numbers/strings in expressions - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 37&t=55905

Re: Bug: StrSplit

Posted: 03 Nov 2018, 03:23
by rodemp
I did not know it would be a problem in the simple part. Thanks for helping solve the problem.

Re: Bug: StrSplit

Posted: 03 Nov 2018, 17:00
by Ursi
You can also use the Float and Integer functions to convert strings to numbers.

Re: Bug: StrSplit

Posted: 25 Feb 2019, 06:30
by _3D_
As jeeswg wrote you compare string to string.
If you need to compare separated elements as integer: (spl[<index>] + 0) <comparison> (spl[<index>] + 0) - it is forced conversion to integer if possible or exception.

Re: Bug: StrSplit

Posted: 07 Jun 2019, 16:30
by jeeswg
- I'd like to compile a custom version of AHK v2 that uses the old behaviour, i.e. compare anything that looks numeric, numerically, unless both items are forced as strings at the point where they are compared.
- This example demonstrates what changed:

Code: Select all

a := "1", b := "1.0"
MsgBox(a = b) ;0 (newer versions), 1 (older versions, preferable)
MsgBox(A_AhkVersion)
- Does anyone know where the changed code (re. comparison behaviour) is located in the source code?
- Or in which version it changed? (By testing available exes, I know that the newer behaviour was in force from at least v2.0-a038 onwards.)

- Some source code search terms: SYM_LTOE (less than or equal), this_infix_item.
- Perhaps it's the IsPureNumeric function, introduced in this commit:
Revised handling of types (integer/float/string). · Lexikos/AutoHotkey_L@275216e · GitHub
https://github.com/Lexikos/AutoHotkey_L/commit/275216e20724568ba7afbe6f2cc29297fd162be2
- [EDIT:] Here's a quick fix (although it goes too far, comparing forced strings that look numeric as numeric):

Code: Select all

;quick fix (script_expression.cpp):
;before:
			if (  !(right_is_number && left_is_number)  // i.e. they're not both numeric (or this is SYM_CONCAT).
				|| IS_RELATIONAL_OPERATOR(this_token.symbol) && !right_is_pure_number && !left_is_pure_number  ) // i.e. if both are strings, compare them alphabetically.

;after:
			if (  !(right_is_number && left_is_number)  // i.e. they're not both numeric (or this is SYM_CONCAT).
				|| false) // i.e. if both are strings, compare them alphabetically.
- Now I need info re. AHK v1, how it detects operands that were forced as strings.