# Bitwise operations with 64 bit integers

## Recommended Posts

Hi guys,

Bitwise operations in Autoit is possible only till 32 bit integers, but sometimes WinAPI requires to process 64 bit vectors... so?

So you can use this little UDF to handle properly those integers!

```Func _BitAND64(\$iValue1, \$iValue2)
If Not ((VarGetType(\$iValue1) = "Int64") Or (VarGetType(\$iValue2) = "Int64")) Then Return BitAND(\$iValue1, \$iValue2)
\$iValue1 = __DecToBin64(\$iValue1)
\$iValue2 = __DecToBin64(\$iValue2)
Local \$aValueANDed[64], \$i
For \$i = 0 To 63
\$aValueANDed[\$i] = (\$iValue1[\$i] And \$iValue2[\$i]) ? 1 : 0
Next
Return __BinToDec64(\$aValueANDed)
EndFunc   ;==>_BitAND64

Func _BitOR64(\$iValue1, \$iValue2)
If Not ((VarGetType(\$iValue1) = "Int64") Or (VarGetType(\$iValue2) = "Int64")) Then Return BitOR(\$iValue1, \$iValue2)
\$iValue1 = __DecToBin64(\$iValue1)
\$iValue2 = __DecToBin64(\$iValue2)
Local \$aValueORed[64], \$i
For \$i = 0 To 63
\$aValueORed[\$i] = (\$iValue1[\$i] Or \$iValue2[\$i]) ? 1 : 0
Next
Return __BinToDec64(\$aValueORed)
EndFunc   ;==>_BitOR64

Func _BitXOR64(\$iValue1, \$iValue2)
If Not ((VarGetType(\$iValue1) = "Int64") Or (VarGetType(\$iValue2) = "Int64")) Then Return BitXOR(\$iValue1, \$iValue2)
\$iValue1 = __DecToBin64(\$iValue1)
\$iValue2 = __DecToBin64(\$iValue2)
Local \$aValueXORed[64], \$i
For \$i = 0 To 63
\$aValueXORed[\$i] = ((\$iValue1[\$i] And (Not \$iValue2[\$i])) Or ((Not \$iValue1[\$i]) And \$iValue2)) ? 1 : 0
Next
Return __BinToDec64(\$aValueXORed)
EndFunc   ;==>_BitXOR64

Func _BitNOT64(\$iValue)
If Not (VarGetType(\$iValue) = "Int64") Then Return BitNOT(\$iValue)
\$iValue = __DecToBin64(\$iValue)
For \$i = 0 To 63
\$iValue[\$i] = Not \$iValue[\$i]
Next
Return __BinToDec64(\$iValue)
EndFunc   ;==>_BitNOT64

Func __DecToBin64(\$iDec)
Local \$tDec = DllStructCreate("int64 num"), \$aBin[64], \$bBit, \$i
\$tDec.num = \$iDec
For \$i = 0 To 63
\$bBit = (Mod(\$tDec.num, 2) ? 1 : 0)
\$aBin[63 - \$i] = \$bBit
\$tDec.num = Floor(\$tDec.num / 2)
Next
Return \$aBin
EndFunc   ;==>__DecToBin64

Func __BinToDec64(\$aBin)
Local \$tDec = DllStructCreate("int64 num"), \$i
If \$aBin[0] Then \$tDec.num += 0x8000000000000000 ;2^63 = 9223372036854775808, but for Autoit the world ends at 9223372036854775807 (2^63 - 1)
For \$i = 1 To 63
If \$aBin[\$i] Then \$tDec.num += 2 ^ (63 - \$i)
Next
Return \$tDec.num
EndFunc   ;==>__BinToDec64```

If you are working with unsigned 64 bit integers and these functions return a negative value, don't worry, bitwise operations come out well, but Autoit manages all numbers as signed integers.

Spoiler

Some UDFs I created:

##### Share on other sites

• 3 years later...

Since no-one has commented on these yet after so many years, and this is the first hit in Google when you search for 64-bit bitwise operations in AutoIt...

I'm sorry to report these functions are completely broken. All of them.

The reason for this is because your functions are mixing together data types Integer and Double in the arithmetic operations.

An example using ...

`_BitAND64(0xFFFFFFFFFFFFFFFF, 0x1111111111111111)`

... gives the incorrect result 0x1111111111112201 (correct result should be 0x1111111111111111).

Examples of operations from your UDF that will result in type Double:

```\$tDec.num = Floor(\$tDec.num / 2)
../..
\$tDec.num += 2 ^ (63 - \$i)```

Both the / and ^ operators are no-no if you want Integers. It doesn't matter if the result is a whole number, the type will still be Double.

As a solution, you need to split the values into hi DWORD and lo DWORD, perform the bitwise operation on the hi and lo DWORDs separately, and then simply merge the two DWORDS into a QWORD.

For example:

```Func _BitAND64(\$_iValue1, \$_iValue2)
If (VarGetType(\$_iValue1)<>"Int64" And VarGetType(\$_iValue2)<>"Int64") Then Return Int(BitAND(\$_iValue1, \$_iValue2), \$NUMBER_64BIT)
Local \$_dHiDWORD1 = Dec(StringLeft(Hex(\$_iValue1, 16), 8))
Local \$_dLoDWORD1 = Int(\$_iValue1, \$NUMBER_32BIT)
Local \$_dHiDWORD2 = Dec(StringLeft(Hex(\$_iValue2, 16), 8))
Local \$_dLoDWORD1 = Int(\$_iValue2, \$NUMBER_32BIT)
Return Dec(Hex(BitAND(\$_dHiDWORD1, \$_dHiDWORD2), 8) & Hex(BitAND(\$_dLoDWORD1, \$_dLoDWORD2), 8), \$NUMBER_64BIT)
EndFunc```

This also ensures the return value is always a QWORD (Int64), as the name of the function implies.

As a bonus, by  getting rid of the use of DllStructCreate(), you speed up the function with maybe 50x times or more.

Edited by Irios

discord.me/autoit  (unofficial)

## Create an account

Register a new account

• ### Similar Content

• #### AutoIT Language: Why BitAND is not an infix statement

By Robinson1,

• 9 replies
• 1,608 views
• #### [Solved] Get Full Path of process - both x86 & x64.

By iXX,

• 3 replies
• 4,895 views
• #### bitAND magic numbers help

By 232showtime,

• 3 replies
• 1,615 views
• #### _WinAPI_EnumProcessModules error 10

By AutID,

• 10 replies
• 3,282 views
• #### make script faster 1 2

By andygo,

• 35 replies
• 7,787 views
×

• Wiki

• Back

• #### Beta

• Git
• FAQ
×
• Create New...