Ich hab jetzt meine BigNum Version in ASM umgesetzt
Für eine etwa 40.000 stellige Dezimalzahl braucht es ca 25ms:
Edit: Durch kleines Speedupdate nu ca 20ms
Spoiler anzeigen
#AutoIt3Wrapper_UseX64=n
[/autoit] [autoit][/autoit] [autoit];#include "FASM.au3"
[/autoit] [autoit][/autoit] [autoit];Global $bOPCode = _FASM_Compile("_ASM_DecToHex32")
Global $_pASM_DecToHex = _FASM_StructCreateBCA16("0x5589E583EC048B75088B4D0C8B551089F7F30F6F3AF30F6F7210F30F6F6A20660FEFE4F30F6F5A3031DB909090909090F30F6F06660FFAC7660F6FC8660F60C4660FF5C5660F3840C3660F3802C0660F3802C0660FDBCE660F73D908660FFEC1660F7E0783C30183C60983C70483E9097FBE8B750889F789D9890C24BB00CA9A3B9090909090909090909090909090908B0C2489FE31C090909090909090909031D2F7E3030683D200891683C60483E9017FED890783C704832C24017FD283C4045DC20C00")
;$bOPCode = _FASM_Compile("_ASM_HexToStr32")
Global $_pASM_HexToStr = _FASM_StructCreateBCA16("0x8B7424048B4C24088B7C240C01CE66BBF00F83EE018A0688C46621D8C0E8043C0A7C020407043080FC0A7C0380C40780C43066890783C70283E9017FD5C20C00")
;$bOPCode = _FASM_Compile("_ASM_HexToBinStr32")
Global $_pASM_HexToBinStr = _FASM_StructCreateBCA16("0x8B7424048B4C24088B7C240C01CE66BBF00F83EE018A0688C46621D8C0E804BA30303030A801740681CA00000001A802740681CA00000100A804740681CA00010000A808740383CA01891783C704BA30303030F6C401740681CA00000001F6C402740681CA00000100F6C404740681CA00010000F6C408740383CA01891783C70483E9017F8CC20C00")
$sDec = "1234567890"
[/autoit] [autoit][/autoit] [autoit]For $i = 1 To 12
$sDec &= $sDec
Next
ConsoleWrite("! Dec Len: " & StringLen($sDec) & @CRLF & "> " & $sDec & @CRLF & @CRLF)
[/autoit] [autoit][/autoit] [autoit]Global $iTimer = TimerInit()
$sHex = _BigDecToHex($sDec)
ConsoleWrite("! Time: " & TimerDiff($iTimer) & @CRLF & @CRLF)
ConsoleWrite("> " & $sHex & @CRLF & @CRLF)
Func _BigDecToHex(ByRef $sDec, $iMode = 2)
Local $iLen = StringLen($sDec)
If Mod($iLen, 9) Then
$iLen += 9 - Mod($iLen, 9)
$sDec = StringRight("000000000" & $sDec, $iLen)
EndIf
Local $tDec = DllStructCreate("char[" & $iLen & "]; byte[16];")
DllStructSetData($tDec, 1, $sDec)
Local $tVal = DllStructCreate("byte[64];")
DllStructSetData($tVal, 1, "0x303030303030303030303030303030300000000000000000FF000000000000001027E80364000A001027E80364000A0010270000102700000100000001000000")
DllCallAddress("none", $_pASM_DecToHex, "struct*", $tDec, "uint", $iLen, "struct*", $tVal)
[/autoit] [autoit][/autoit] [autoit]Switch $iMode
Case 1 ;Hex String
Local $tHex = DllStructCreate("char[" & $iLen & "];")
DllCallAddress("none", $_pASM_HexToStr, "struct*", $tDec, "uint", $iLen / 18 * 8, "struct*", $tHex)
Return StringRegExpReplace(DllStructGetData($tHex, 1), "^0+([^0]|0$)", "\1", 1)
Case 2 ;Bin String
Local $tBin = DllStructCreate("char[" & $iLen * 4 & "];")
DllCallAddress("none", $_pASM_HexToBinStr, "struct*", $tDec, "uint", $iLen / 18 * 8, "struct*", $tBin)
Return StringRegExpReplace(DllStructGetData($tBin, 1), "^0+([^0]|0$)", "\1", 1)
Case Else ;Hex
Local $tHex = DllStructCreate("byte[" & Ceiling($iLen / 18 * & "];", DllStructGetPtr($tDec))
Return DllStructGetData($tHex, 1)
EndSwitch
EndFunc ;==>_BigDecToHex
#ASM _ASM_DecToHex32
# use32
# push ebp
# mov ebp, esp
# sub esp, 4
;#######################################################
;# Char to NumberArray
;#######################################################
# mov esi, [ebp+8]
# mov ecx, [ebp+12]
# mov edx, [ebp+16]
# mov edi, esi
[/autoit] [autoit][/autoit] [autoit]# movdqu xmm7, [edx]
# movdqu xmm6, [edx+16]
# movdqu xmm5, [edx+32]
# pxor xmm4, xmm4
# movdqu xmm3, [edx+48]
;xmm7 = 0x30303030303030303030303030303030
;xmm6 = 0x0000000000000000FF00000000000000
;xmm5 = 10000, 1000, 100, 10, 10000, 1000, 100, 10
;xmm4 = 0, 0, 0, 0
;xmm3 = 10000, 10000, 1, 1
# xor ebx, ebx
# align 16
# _LoopChar:
# movdqu xmm0, [esi]
# psubd xmm0, xmm7
# movdqa xmm1, xmm0
# punpcklbw xmm0, xmm4 ;Char 1-8
# pmaddwd xmm0, xmm5
# pmulld xmm0, xmm3
# phaddd xmm0, xmm0
# phaddd xmm0, xmm0 ;12345678.
# pand xmm1, xmm6
# psrldq xmm1, 8
# paddd xmm0, xmm1 ;123456789
# movd [edi], xmm0
[/autoit] [autoit][/autoit] [autoit]# add ebx, 1
# add esi, 9
# add edi, 4
# sub ecx, 9
# jg _LoopChar
;#######################################################
;# BigDiv
;#######################################################
# mov esi, [ebp+8]
# mov edi, esi
# mov ecx, ebx
# mov [esp], ecx
# mov ebx, 1000000000
;eax = Number/Result
;ebx = MulFactor
;ecx = Count
;edx = Result
# align 16
# _LoopDiv:
# mov ecx, [esp]
# mov esi, edi
# xor eax, eax ;Tmp = 0
[/autoit] [autoit][/autoit] [autoit]# align 16
# _LoopBigDiv:
# xor edx, edx ;???
# mul ebx ;carry * 100000000
# add eax, [esi]
# adc edx, 0
# mov [esi], edx
[/autoit] [autoit][/autoit] [autoit]# add esi, 4
# sub ecx, 1
# jg _LoopBigDiv
# mov [edi], eax ;write carry
[/autoit] [autoit][/autoit] [autoit]# add edi, 4 ;next ArrayIndex
# sub dword[esp], 1
# jg _LoopDiv
# add esp, 4
# pop ebp
# ret 12
#ASMEND
#ASM _ASM_HexToBinStr32
# use32
# mov esi, [esp+4]
# mov ecx, [esp+8]
# mov edi, [esp+12]
# add esi, ecx
# mov bx, 0x0FF0
# _Loop:
# sub esi, 1
# mov al, [esi]
# mov ah, al
# and ax, bx
# shr al, 4
# mov edx, 0x30303030
# test al, 1
# jz _L2
# or edx, 0x01000000
# _L2:
# test al, 2
# jz _L4
# or edx, 0x00010000
# _L4:
# test al, 4
# jz _L8
# or edx, 0x00000100
# _L8:
# test al, 8
# jz _H1
# or edx, 0x00000001
# _H1:
# mov [edi], edx
# add edi, 4
# mov edx, 0x30303030
# test ah, 1
# jz _H2
# or edx, 0x01000000
# _H2:
# test ah, 2
# jz _H4
# or edx, 0x00010000
# _H4:
# test ah, 4
# jz _H8
# or edx, 0x00000100
# _H8:
# test ah, 8
# jz _HN
# or edx, 0x00000001
# _HN:
# mov [edi], edx
# add edi, 4
# sub ecx, 1
# jg _Loop
# ret 12
#ASMEND
#ASM _ASM_HexToStr32
# use32
# mov esi, [esp+4]
# mov ecx, [esp+8]
# mov edi, [esp+12]
# add esi, ecx
# mov bx, 0x0FF0
# _Loop:
# sub esi, 1
# mov al, [esi]
# mov ah, al
# and ax, bx
# shr al, 4
# cmp al, 0xA
# jl _Dec
# add al, 7
# _Dec:
# add al, 0x30
# cmp ah, 0xA
# jl _Dec2
# add ah, 7
# _Dec2:
# add ah, 0x30
# mov [edi], ax
# add edi, 2
# sub ecx, 1
# jg _Loop
# ret 12
#ASMEND
;#cs
Func _FASM_StructCreateBCA16($bBinaryCode)
Local $iSize = BinaryLen($bBinaryCode)
Local $aResult = DllCall("kernel32.dll", "ptr", "VirtualAlloc", "ptr", 0, "ulong_ptr", $iSize + 16, "dword", 0x00001000, "dword", 0x00000040)
If @error Or Not $aResult[0] Then Return SetError(1, 0, False)
Local $pStruct = Number($aResult[0])
$pStruct = $pStruct + 16 - Mod($pStruct, 16)
Local $tStruct = DllStructCreate("byte[" & $iSize & "];", $pStruct)
DllStructSetData($tStruct, 1, $bBinaryCode)
Return $pStruct
EndFunc ;==>_FASM_StructCreateBCA16
;#ce
Um die Ergebnisse zu überprüfen, verwende ich übrigens: http://www.mobilefish.com/services/big_number/big_number.php
E