if statement influences floating point number

Report problems with documented functionality
T-Rock
Posts: 27
Joined: 01 Feb 2015, 09:11

if statement influences floating point number

06 Aug 2018, 03:39

I have the following code, which delivers an unexpected result (I guess):

Code: Select all

String := "1525.13000"
if ( String )
	FileAppend, % String . "`n", *
List := [ String ]
FileAppend, % List.1 . "`n", *
Output:
1525.13000
1525.130000

If I comment out the one line with the "if" command, the output matches my expectation:
1525.13000
1525.13000

Why influences the if-statement the floating point number to be expanded to the default of 6 characters after the decimal point?
Also it seems, this behaviour only occurs in combination with an array or an object.
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: if statement influences floating point number

06 Aug 2018, 06:14

When writing the string to the object it will turn into a float number.
After that AHK will turn the float back into a string which adds the 0.
This has the same effect:

Code: Select all

String := "1525.13000"
if ( String )
	FileAppend, % String . "`n", test.log
List := [ String ]
FileAppend, % List.1 . "`n", test.log
if ( String += 0 )
	FileAppend, % String . "`n", test.log
Recommends AHK Studio
T-Rock
Posts: 27
Joined: 01 Feb 2015, 09:11

Re: if statement influences floating point number

06 Aug 2018, 07:15

Thanks for your reply.

But why I get then a different output by just commenting the "if" command?

Code: Select all

String := "1525.13000"
;if ( String )
	FileAppend, % String . "`n", *
List := [ String ]
FileAppend, % List.1 . "`n", *
Output:
1525.13000
1525.13000

As is doesn't matter, if I use String := "1525.13000" or String := 1525.13000, I am not sure if it is maybe always a floating point number without converting it.
And why is it adding a zero while converting it?
User avatar
Flipeador
Posts: 1204
Joined: 15 Nov 2014, 21:31
Location: Argentina
Contact:

Re: if statement influences floating point number

06 Aug 2018, 08:13

Who knows the weird things that v1 does. :crazy:

Reading Variables\Expressions "Integers and floating point", it seems that when you use the variable in an expression, and it is a number, AHK automatically converts it to Float type (if it contain a decimal point) (as nnnik said).

Code: Select all

String := "1525.13000"
foo := String + 1
List := [ String ]
MsgBox % List[1] "`n" String
Edit* Oh wait, this does not explain what you are saying. :oops:

Code: Select all

String := "1525.13000"
foo := String + 1

MsgBox % StrGet(&String, "UTF-16")   ; I imagine that this is due to the deactivation of the caching of binary numbers in that variable

a := [ String ]
MsgBox % a[1]
:shock:
Edit2* Read https://autohotkey.com/docs/Concepts.htm#caching.

Of course, this does not happen in AHKv2. Because AHKv2 distinguishes between strings and numbers.

Code: Select all

String := "1525.13000"
foo := String + 1
List := [ String ]
MsgBox List[1] "`n" String "`n" Type(List[1])
Instead in v1 the numbers are stored as a string.

Code: Select all

; store the "number" 46 in the variable «num».
num := 46

; gets the memory address of «num».
ptr := &num

; retrieve and display the number
MsgBox % StrGet(ptr, "UTF-16")

Code: Select all

; AHKv2
num := 46
ptr := &num

MsgBox NumGet(ptr, "Int64")
T-Rock
Posts: 27
Joined: 01 Feb 2015, 09:11

Re: if statement influences floating point number

06 Aug 2018, 08:39

Thanks for the detailed explanation.
I try hard to get it in my head, but it is maybe too hot in Germany these days ...

So here if ( String ) I used the variable as an expression, that's why it is converted to a floating point number, right?

But why is it not converted, if I do this?:

Code: Select all

String := "1525.13000"
if ( String != "" )
	MsgBox, % String
List := [ String ]
MsgBox % List[1] "`n" String
Btw I don't want to have it converted, so this would be the solution?
User avatar
Flipeador
Posts: 1204
Joined: 15 Nov 2014, 21:31
Location: Argentina
Contact:

Re: if statement influences floating point number

06 Aug 2018, 08:45

Looking a little more in detail, I think it's about this:
Object - Keys wrote:Quoted literal strings are considered purely non-numeric in v1.x, so x[1] and x["1"] are not equivalent. Additionally, if a quoted literal string is concatenated with another value (as in "0x" x), the result is treated as purely non-numeric. However, this does not apply to variables, so x[1] and x[y:="1"] are equivalent. This issue will be resolved in AutoHotkey v2, so scripts should avoid using quoted numeric literals as keys.
https://autohotkey.com/docs/Objects.htm#Keys
Caching wrote:Although a variable is typically thought of as holding a single value, and that value having a distinct type (string, number or object), AutoHotkey automatically converts between numbers and strings in cases like myString + 1 and MsgBox %myNumber%. As these conversions can happen very frequently, whenever a variable is converted, the result is cached in the variable.
https://autohotkey.com/docs/Concepts.htm#caching
T-Rock wrote:But why is it not converted, if I do this?:
It seems that the variable is not affected in these cases. Because AHK decides so. :|
T-Rock
Posts: 27
Joined: 01 Feb 2015, 09:11

Re: if statement influences floating point number

06 Aug 2018, 09:01

Thanks again.
This explains the difference with objects.
I had no idea about the caching thing.

Maybe I should start looking at v2 ;)
User avatar
Flipeador
Posts: 1204
Joined: 15 Nov 2014, 21:31
Location: Argentina
Contact:

Re: if statement influences floating point number

06 Aug 2018, 09:06

Sorry I can not give you a better explanation, I have no idea how AHK works internally.
AHKv2 has better performance. :)
:wave:
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: if statement influences floating point number

06 Aug 2018, 09:55

When writing the string to the object it will turn into a float number.
No, when using the variable in an expression in which it is used a number it will cache a float.
Objects don't have the capability to store both a number and a string as a key or value. Since numbers are more memory-efficient, if a variable has both, the number is used
When an expression is required to evaluate to true or false (such as an IF-statement), a blank or zero result is considered false and all other results are considered true
Edit: wrong quote
Another way to examplify,

Code: Select all

string := "0.0"
if (string)
	msgbox	; doesn't happen
But why is it not converted, if I do this?:
String != "" is string compairson, it doesn't require the number to cached. For example. String+0 != "" will cache it.
You can do (&string) before storing it in the object to disable the caching, consequently storing it as a string, that is,

Code: Select all

(&string)
List := [ String ]
It is messy, v2 is better, but still, the msgbox in the above example is not shown in v2 either :cry: .

Cheers.
Last edited by Helgef on 06 Aug 2018, 12:42, edited 1 time in total.
User avatar
Flipeador
Posts: 1204
Joined: 15 Nov 2014, 21:31
Location: Argentina
Contact:

Re: if statement influences floating point number

06 Aug 2018, 10:36

Helgef wrote:It is messy, v2 is better, but still, the msgbox in the above example is not shown in v2 either
I think this should be true in AHKv2:

Code: Select all

s := "0"
MsgBox s ? 1 : 0

s := "0" . Chr(0)
MsgBox s ? 1 : 0

s := Chr(0)
MsgBox s ? 1 : 0   ; OK
:!:
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: if statement influences floating point number

06 Aug 2018, 11:16

- Re. displaying variables as strings/numbers.
- The 'if' line appears to have no effect on the variable vNum, when you do FileAppend vNum, it always outputs a string.
- What does appear to have an effect, on what FileAppend outputs, is how you store the variable in the array. E.g. when you do FileAppend [vNum].1 or FileAppend["" vNum].1.
- E.g. here I store the variable raw and as a string in 2 different keys:
oArray := [vNum, "" vNum]

Code: Select all

q:: ;check if 'if vNum' affects the output
vPath := A_Desktop "\z " A_Now ".txt"
vNum := "123.123"
FileAppend, % vNum "`r`n", % "*" vPath, UTF-8 ;123.123
FileAppend, % vNum "`r`n", % "*" vPath, UTF-8 ;123.123
if vNum
	FileAppend, % vNum "`r`n", % "*" vPath, UTF-8 ;123.123
oArray := [vNum, "" vNum]
FileAppend, % oArray.1 "`r`n", % "*" vPath, UTF-8 ;123.123000
FileAppend, % oArray.2 "`r`n", % "*" vPath, UTF-8 ;123.123
Run, % vPath
return
- [EDIT:] This slightly amended version of the test code suggests that [vNum] initially stores a string, but following 'if vNum', it stores a float. This suggests that 'if vNum' affects the variable in some way, however, when you do FileAppend vNum, it consistently outputs a string.

Code: Select all

q:: ;check if 'if vNum' affects the output
vPath := A_Desktop "\z " A_Now ".txt"
vNum := "123.123"
FileAppend, % vNum "`r`n", % "*" vPath, UTF-8 ;123.123
FileAppend, % vNum "`r`n", % "*" vPath, UTF-8 ;123.123
FileAppend, % "`r`n", % "*" vPath, UTF-8

oArray := [vNum, "" vNum]
FileAppend, % oArray.1 "`r`n", % "*" vPath, UTF-8 ;123.123
FileAppend, % oArray.2 "`r`n", % "*" vPath, UTF-8 ;123.123
FileAppend, % "`r`n", % "*" vPath, UTF-8

if vNum
	Sleep, 0
oArray := [vNum, "" vNum]
FileAppend, % oArray.1 "`r`n", % "*" vPath, UTF-8 ;123.123000
FileAppend, % oArray.2 "`r`n", % "*" vPath, UTF-8 ;123.123
FileAppend, % "`r`n", % "*" vPath, UTF-8
Run, % vPath
return
- [EDIT:] Here is a more complete test script:

Code: Select all

q:: ;check if 'if vNum' affects the output
vPath := A_Desktop "\z " A_Now ".txt"

Loop, 4
{
	vIndex := A_Index
	Loop, 2
	{
		if (A_Index = 1)
			vNum := "123.123"
			;vNum := "000123"
		else
		{
			if vNum
				Sleep, 0
		}

		(vIndex = 2) && (oArray := [vNum])
		(vIndex = 3) && (oArray := ["" vNum])
		(vIndex = 4) && (oArray := [0 + vNum])
		if (vIndex = 1)
			FileAppend, % vNum "`r`n", % "*" vPath, UTF-8
		else
			FileAppend, % oArray.1 "`r`n", % "*" vPath, UTF-8
	}
	FileAppend, % "`r`n", % "*" vPath, UTF-8
}
Run, % vPath
return

;==================================================

;results:

;vNum:
;123.123 ;string
;123.123 ;string

;[vNum]
;a discrepancy:
;the use of 'if vNum' (a read operation),
;has had a write effect,
;and as a result, a float was stored, not a string
;123.123 ;string
;123.123000 ;float

;["" vNum]
;123.123 ;string
;123.123 ;string

;[0 + vNum]
;123.123000 ;float
;123.123000 ;float

;==================================================
- [EDIT:] The explanation is here:
Concepts and Conventions | AutoHotkey
https://autohotkey.com/docs/Concepts.htm#caching
Objects don't have the capability to store both a number and a string as a key or value. Since numbers are more memory-efficient, if a variable has both, the number is used (except for floating-point values used as keys).
- Mentioned here:
Object.Push is eating initial zeros - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=64932&p=278890#p278890
- vNum contains a string. Doing 'if vNum' requires a string and a numerical comparison. So a number is cached for vNum. There is now both a string and a number associated with vNum. When [vNum] is done, as described above, the number stored, and not the string.
Last edited by jeeswg on 30 May 2019, 08:05, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: if statement influences floating point number

06 Aug 2018, 12:50

The 'if' line appears to have no effect on the variable.
Yes, it suddenly stopped having an effect on the variable, strange :think:.
Spoiler
joefiesta
Posts: 494
Joined: 24 Jan 2016, 13:54
Location: Pa., USA

Re: if statement influences floating point number

10 Aug 2018, 09:45

Yes, strings should never be interpreted as numbers, imo.
I don't think there is ANYTHING humble about your opinion. It should be carved in stone. If not so in V2 (which I have yet to use), something needs to be changed there.
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: if statement influences floating point number

10 Aug 2018, 09:52

I think you both are wrong.
Recommends AHK Studio

Return to “Bug Reports”

Who is online

Users browsing this forum: No registered users and 33 guests