Sign in to follow this  
Followers 0
Fzarada

Help: Bignum Multiplication

7 posts in this topic

Hi all,

Is there a way to overcome AutoIt 64 bit unsigned integer limitation in basic calculations?

I need to multiply a DWord size integer by a Word size integer, then work on the Most Significant DWord of the the whole QWord resulting.

For exemple:

0xE6C2B449 * 0x0D68 = FFFFFEAD:A240F2A8

The part that interest me is FFFFFEAD, but i can get it with simple multiplication, AutoIt will return only the DWord size A240F2A8

Any ideas?

Share this post


Link to post
Share on other sites



Try using a combination of Bitwise manipulations, string manipulations, as well as a base-10 string-based carryover routine, and store the final result as a string.

Doing so can result in a workaround because strings are not limited to 62 bits, and chopping the values being used into 16-bit sections will allow you to stay well under that 64-bit limit.

Good luck! muttley

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

;0xE6C2B449 * 0x0D68 = FFFFFEAD:A240F2A8

$a = 0xE6C2B449 * 0x0D68/(2^32)

$b = 0xE6C2B449 * 0x0D68/(2^16)

$ans = Dec(StringLeft(Hex($a), 4) & StringLeft(Hex($b), 4))

ConsoleWrite(hex($ans) & @CRLF)

EDIT: not a good idea! See next post.

Edited by martin

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

http://www.autoitscript.com/forum/index.php?showtopic=75388

I guess _WinAPI_HiDWord() is what you're looking for? I also tried similar methods as martin did (division and all), but they didn't turn out too well.

@martin: I don't think that calculation is correct. Trying your method on the number 99321014585765154, for example, yields 0x01608000, where the high dword is actually 0x0160DBEF.

I've been toying around with math again (because using DllStructs isn't sitting well with me), and came up with this formula:

BitShift(Int($iLongLong/4294967296), 16)*65536 + BitAND(Int($iLongLong/4294967296), 65535)

This formula manages to be quicker than both string manipulation and DllStruct fiddling (though I guess anything's faster than the latter xD). It appears to work with all of the numbers I've thrown at it, but I don't know if there are edge cases where it'll fail. In short, I'm still not too happy with this formula either muttley

Edit: Hah, that formula fails for 16045725885737583000 = 0xDEADDEADDEADBEEF ;D It's really just failing on large numbers in general (9223372036854775807, which is smaller than that number, is the highest signed int64 possible in AutoIt anyway). Seems even online calculators fail at converting such large numbers.

Edited by -Ultima-

[ WinINet.au3 | Array.au3 (Optimized) | _UnixTimeParse() ]

Share this post


Link to post
Share on other sites

martin method was right what i needed.

I had come up with a solution quite similar that works for unsigned multiplication:

Since i'm interested in the Most Significant half of the result, I worked on multiplying by the Most Significant half of 0xE6C2B449. Then shift right one Word (16 bits).

; Most Significant DWord of the QWord result
; 0xE6C2B449 * 0x0D68 = 00000C15:A240F2A8
;---------------------------------------------------------

$ab = 0xD68 * 0xE6C2
$MSab = Hex(BitShift($ab,16))

;---------------------------------------------------------
;Returns $MSab = 00000C15

Thank you all muttley

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

http://www.autoitscript.com/forum/index.php?showtopic=75388

I guess _WinAPI_HiDWord() is what you're looking for? I also tried similar methods as martin did (division and all), but they didn't turn out too well.

@martin: I don't think that calculation is correct. Trying your method on the number 99321014585765154, for example, yields 0x01608000, where the high dword is actually 0x0160DBEF.

I've been toying around with math again (because using DllStructs isn't sitting well with me), and came up with this formula:

BitShift(Int($iLongLong/4294967296), 16)*65536 + BitAND(Int($iLongLong/4294967296), 65535)

This formula manages to be quicker than both string manipulation and DllStruct fiddling (though I guess anything's faster than the latter xD). It appears to work with all of the numbers I've thrown at it, but I don't know if there are edge cases where it'll fail. In short, I'm still not too happy with this formula either muttley

Edit: Hah, that formula fails for 16045725885737583000 = 0xDEADDEADDEADBEEF ;D It's really just failing on large numbers in general (9223372036854775807, which is smaller than that number, is the highest signed int64 possible in AutoIt anyway). Seems even online calculators fail at converting such large numbers.

You're right that what I suggested is wrong. I'll edit my post so it doesn't mislead anyone. Edited by martin

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
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
Sign in to follow this  
Followers 0