Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate

# Variable assignment fails at a certain place and that too randomly

Best Answer Lexikos , 26 June 2013 - 09:50 PM

6 replies to this topic
• Members
• 1323 posts
• Last active: Nov 14 2015 06:56 PM
• Joined: 30 Jan 2013

Maths() topic http://www.autohotke...matics-library/

Variables when assigned at places near to or in the function call in which they are used give wrong results.

What I simply mean is --

```var := "-" SM_Multiply(Divisor, div)	;done because of a bug or something

if div = 0
Remainder := 0
else
```

and

```        if div = 0
Remainder := 0
else
Remainder := SM_Add(dividend,  "-" SM_Multiply(Divisor, div))
```

give different results at random situations. As the var doesn't changes anywhere in the middle, the second code seems theoretically correct. But the truth is that second code fails at random situations.

An example to prove this

Please note that the two codes are part of SM_Mod() function in the lib. The second one (snippet:2) is the one included in the v2.4

Try this code in the 2.4 version (link available right at the top)

```msgbox,% SM_Mod( SM_Pow(3,77), 79)   ;Mod of 3**77 when divided by 79
```

The answer should be something less than 79 a/c Maths (actually 53) but the answer comes out to be a 20-digit number

Note that there isn't a bug in SM_Mod() func, you can check simpler or known combos to confirm

Next try replacing the snippet:2 (which is a part of SM_Mod()) with snippet:1, and it will work with 3,77 example.

Any explanations on this ?

Lexikos ?

I have also tried something like this --

```        if div = 0
Remainder := 0
else
{
var :=  "-" SM_Multiply(Divisor, div)
}
```

This too fails ..

Now a CS Undergrad. | My WebsiteAutohotkey Scripts | Softwares

Telegram me : @aviaryan

• 9844 posts
• AutoHotkey Foundation
• Last active:
• Joined: 17 Oct 2006

AutoHotkey does not support integers that large.

For integers, 64-bit signed values are supported, which range from -9223372036854775808 (-0x8000000000000000) to 9223372036854775807 (0x7FFFFFFFFFFFFFFF). Any integer constants outside this range are not supported and might yield inconsistent results.

Change this line:

```if div = 0
```

to this:

```if (div = "0")
```

and your function will work.  You may also change the `0` in the line above, but that probably doesn't matter.

The former compares div and 0 as integers.

• Members
• 1323 posts
• Last active: Nov 14 2015 06:56 PM
• Joined: 30 Jan 2013

Your solution works as expected, Lexikos. Thanks !

The former compares div and 0 as integers.

And then changes div too !
I never thought that comparing a string-number var which is to 0 to nothing but 0 or comparing a string-number var to 0 in vain and going for the else will cause permanent modifications in the variable .
Is it a handy feature ? Can't autohotkey make backups of variables before comparing them OR simply not change variable when they are compared.

Now a CS Undergrad. | My WebsiteAutohotkey Scripts | Softwares

Telegram me : @aviaryan

• 9844 posts
• AutoHotkey Foundation
• Last active:
• Joined: 17 Oct 2006

If you must know, it caches the binary 64-bit integer in the variable for performance.

As I said, AutoHotkey does not support integers that large.  You have used an integer outside the supported range.  In that case, the behaviour is undefined.

• Members
• 1323 posts
• Last active: Nov 14 2015 06:56 PM
• Joined: 30 Jan 2013

If you must know, it caches the binary 64-bit integer in the variable for performance.

Okay, then but why is the div modified. If div is more than 64-bit and it is compared to integer (say 0), the div should be trimmed down to 64-bit only for comparision purposes and the changes should not be permanent

Now a CS Undergrad. | My WebsiteAutohotkey Scripts | Softwares

Telegram me : @aviaryan

• 9844 posts
• AutoHotkey Foundation
• Last active:
• Joined: 17 Oct 2006

You totally missed the point.  It does not modify the string; the string is left untouched.  It stores an additional binary 64-bit integer in the variable so that if the variable is interpreted as a number again, it does not need to perform any conversion.  If you pass `div` to a MsgBox or use ListVars, you will see the same value it had before.

Your problem happened because when you assign one variable to another (either with := or by passing a parameter to a UDF), only the cached integer is copied.  This avoids an additional memory allocation and string copy, which is unnecessary in the majority of cases because the integer can be converted to a string on demand (if it becomes necessary).

Large numbers had been considered by Chris and are intentionally not supported (in this specific case):

// ... Also, integers that are too long (and thus perhaps intended to be a series
// of digits rather than an integer) are not checked because they're partially checked
// at loadtime, and if encountered here at runtime, the mere fact that a cached integer
// exists for that string implies the script has done something to cache it, such as
// "if (var > 15)",
which implies the script is currently using that variable as a number.
// So it seems too rare to justify extra checking such as mLength > MAX_INTEGER_LENGTH.

However, it will always copy the string if it begins with "+" or "0".  Additionally, `x := "" y` assigns only a string (since the assignment operator never sees the variable y, only the result of concatenation).

• Members
• 1323 posts
• Last active: Nov 14 2015 06:56 PM
• Joined: 30 Jan 2013

I understand . It's nothing but a matter of speed and Chris was right in his place.

Thanks for giving your time. I will have to check other functions now .

Now a CS Undergrad. | My WebsiteAutohotkey Scripts | Softwares

Telegram me : @aviaryan