Jump to content

Help: Bignum Multiplication


Recommended Posts

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?

Link to comment
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

Link to comment
Share on other sites

;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.
Link to comment
Share on other sites

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() ]

Link to comment
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

Link to comment
Share on other sites

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.
Link to comment
Share on other sites

  • 3 months later...

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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...