Ich seh schon, wird Zeit, dass ich mir mal ein 64Bit BS besorge....thx fürs Testen jedenfalls!
Beiträge von Andy
-
-
Danke Oscar, liegt wohl daran, dass es bei 64Bit zwei der "user.dll" gibt....und ich die "falsche" benutze
-
eine Steilvorlage für Assemblerprogrammierer (oder die, die es werden wollen^^)
Invertieren heisst auf Bitmapbearbeiterisch nämlich XOR 0xFFFFFF
Das geht natürlich auch Pixel für Pixel in AutoIt, oder aber in Assembler
per XOR kann man nämlich direkt Speicherzellen bearbeiten (in diesem Fall invertieren)
XOR [Speicher],0xFFFFFF
invertiert somit das Pixel. Mit das einfachste, was man in Assembler machen kannSpoiler anzeigen
[autoit];#include <AssembleIt.au3>
[/autoit] [autoit][/autoit] [autoit]
#include <GDIPlus.au3>_GDIPlus_Startup()
[/autoit] [autoit][/autoit] [autoit]
$file = FileOpenDialog("Grafikdatei öffnen", @ScriptDir, "Bilder (*.jpg;*.bmp;*.png)")
If @error Then Exit
$hBitmap = _GDIPlus_BitmapCreateFromFile($file)
$iWidth = _GDIPlus_ImageGetWidth($hBitmap)
$iHeight = _GDIPlus_ImageGetHeight($hBitmap)$hBitmapData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iWidth, $iHeight, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32RGB)
[/autoit] [autoit][/autoit] [autoit]
$Scan = DllStructGetData($hBitmapData, "Scan0") ;Pointer auf bitmapdaten(Pixel);$ret=_AssembleIt("ptr","_invertieren","ptr", $scan, "int", $iWidth * $iHeight) ;ptr als Rückgabe, um die hexzahlen schön zu sehen
[/autoit] [autoit][/autoit] [autoit]
;oder
Global $tCodeBuffer = DllStructCreate("byte[23]") ;reserve Memory for opcodes
DllStructSetData($tCodeBuffer, 1, "0x8B7424048B4C24088136FFFFFF0083C60483E90177F2C3") ;write opcodes into memory
$ret = DllCall("user32.dll", "ptr", "CallWindowProcW", "ptr", DllStructGetPtr($tCodeBuffer), "ptr", $Scan, "int", $iWidth * $iHeight, "int", 0, "int", 0)_GDIPlus_BitmapUnlockBits($hBitmap, $hBitmapData)
[/autoit] [autoit][/autoit] [autoit]
_GDIPlus_ImageSaveToFile($hBitmap, "invert.jpg")ShellExecute("invert.jpg")
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit];~ Func _invertieren()
[/autoit] [autoit][/autoit] [autoit]
;~ _("use32") ;sollte immer eingesetzt werden!;~ _("mov esi,dword[esp+4]") ;Startadresse Bitmapdaten (Pixel)
[/autoit] [autoit][/autoit] [autoit]
;~ _("mov ecx,dword[esp+8]") ;anzahl Pixel;~ _("_schleife:") ;so lange, bis ecx=0
[/autoit] [autoit][/autoit] [autoit][/autoit]
;~ _("xor dword[esi],0xFFFFFF") ;Pixel invertieren
;~ _("add esi,4") ;adresse nächstes Pixel
;~ _("sub ecx,1") ;schleifendurchgang
;~ _("ja _schleife") ;so lange, bis ecx=0
;~ _("ret ")
;~ EndFunc ;==>_invertierenGeht auch bissl kürzer, aber so ist es verständlicher
/EDIT/ Funktioniert das so eigentlich auch in 64Bit BS?
-
@sprenger, bei weißem Hintergrund hast du Recht, wenn man allerdings ein Bild als Hintergrund hat, dann kopiert man nur die entsprechenden Bildteile, um die von den Ellipsen überdeckten Bereiche zu "löschen". Da sämtliche durch die GDI-Funktionen bearbeiteten Daten komplett über den Bus zur Graka geschoben werden, ist es schon ein Unterschied, ob man 1920x1080 Pixel über den Bus jagt, oder nur 50x50. Pro Frame natürlich.
Zitatund wie?
Du weisst, an welcher Position die "alte" Ellipse gezeichnet wurde. Diese bedeckt nur einen kleinen Teil des Hintergrundes. Anstatt nun den kompletten Hintergrund (Backbuffer) mit dem Hintergrund zu überschreiben um die winzige Ellipse zu "löschen", überschreibt man nur den Teil des Hintergrundes, der von der Ellipse bedeckt wird.
Wenn deine Ellipse 30x30 Pixel gross ist, kopiere aus dem Hintergund die Fläche an der Position der Ellipse (30x30 Pixel) in den Backbuffer und danach die "neue" Ellipse.In AutoIt könnte es damit irgendwann kritisch werden, da der Verwaltungsaufwand bzw der Overhead der GDI-Funktionsaufrufe bei vielen kleinen Sprites die Geschichte eher verlangsamt. Aber wer "richtig schnell" Grafiken darstellen möchte, dem bleibt nur übrig, so wenige Pixel wie möglich zu bearbeiten.
-
Zitat
Ich bräuchte eine asm-Funktion die WinApi_StretchBlt ersetzen kann, aber schneller ist
ja, das wäre sicher machbar, allein durch SSE wäre da einiges rauszuholen. Wozu brauchst du etwas derart schnelles? Stretchblt() hat jedenfalls bei mir noch nie für Verzögerungen gesorgt, da hängts grösstenteils an ganz anderen Punkten

Ich muss erstmal die anderen Baustellen fertigbekommen... -
hi,
wie du schon bemerkt hast, überschreibt _GDIPlus_GraphicsClear nur den bestehenden Graphic-context mit einer Farbe.
Du musst dein Bild benutzen, um darauf die Ellipsen zu zeichnen.
Bild in Backbuffer, Ellipsen in Backbuffer, aklles weitere in Backbuffer, zum Schluss Backbuffer in GUI kopieren./edit/ wenn es zu langsam ist, immer das komplette Bild in den Backbuffer zu zeichnen, erstelle eine Kopie des Bildes und kopiere immer nur den kleinen Teil, der durch die Ellippsen überschrieben wurde.
-
Zitat
Mit der linearen Funktionsgleichung ist es gut umsetzbar für den linken Strahl aber nicht für den rechten
weil der bei ($Width|$Height) anfängt und auf ($Mouse[0]|$Mouse[1]) geht.wieso?
Der Geradengleichung y=mx+b ist es völlig schnurz, welche Koordinaten gewählt werden. Bis auf den Fall, dass delta x = 0 ist (Gerade senkrecht zur x-Achse) sollte es kein Problem geben!Spoiler anzeigen
[autoit]#include <GDIPlus.au3>
[/autoit] [autoit][/autoit] [autoit]
#include <GuiConstants.au3>Opt("GuionEventmode",1)
[/autoit] [autoit][/autoit] [autoit]_GDIPlus_Startup()
[/autoit] [autoit][/autoit] [autoit]$Width = 800
[/autoit] [autoit][/autoit] [autoit]
$Height = 600$hWnd = GUICreate("Test",$Width,$Height)
[/autoit] [autoit][/autoit] [autoit]GUISetOnEvent($GUI_EVENT_CLOSE,"_Exit")
[/autoit] [autoit][/autoit] [autoit]GUISetState(@SW_SHOW)
[/autoit] [autoit][/autoit] [autoit]Global $hPen = _GDIPlus_PenCreate(0xFFFF0000,5)
[/autoit] [autoit][/autoit] [autoit]Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
[/autoit] [autoit][/autoit] [autoit]Global $hBitmap = _GDIPlus_BitmapCreateFromGraphics($Width, $Height, $hGraphics)
[/autoit] [autoit][/autoit] [autoit]
Global $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)Global $hFGBitmap = _GDIPlus_BitmapCreateFromGraphics($Width,$Height, $hGraphics)
[/autoit] [autoit][/autoit] [autoit]
Global $hFGBackbuffer = _GDIPlus_ImageGetGraphicsContext($hFGBitmap);koordinaten der ecken
[/autoit] [autoit][/autoit] [autoit]
$x0=0;links
$y0=$Height
$x1=$width;rechts
$y1=$Height
$step=5 ;schrittweite der punkteWhile 1
[/autoit] [autoit][/autoit] [autoit]
$Mouse = GUIGetCursorInfo($hWnd)_GDIPlus_GraphicsClear($hFGBackbuffer,0xFFFFFFFF)
[/autoit] [autoit][/autoit] [autoit]
;~ If $Mouse[2] = 1 Then
;links
$m=($mouse[1]-$y0)/($mouse[0]-$x0)
$b=$mouse[1]-$m*$mouse[0]
for $x=$x0 to $mouse[0] step $step
$y=$m*$x+$b;y-koordinate
_GDIPlus_GraphicsDrawEllipse($hGraphics, $X, $Y, 2, 2, $hPen)
next;rechts
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
$m=($mouse[1]-$y1)/($mouse[0]-$x1)
$b=$mouse[1]-$m*$mouse[0]
for $x=$x1 to $mouse[0] step -$step
$y=$m*$x+$b;y-koordinate
_GDIPlus_GraphicsDrawEllipse($hGraphics, $X, $Y, 2, 2, $hPen)
next;~ _GDIPlus_GraphicsDrawLine($hFGBackbuffer,0,$Height,$Mouse[0],$Mouse[1],$hPen)
[/autoit] [autoit][/autoit] [autoit]
;~ _GDIPlus_GraphicsDrawLine($hFGBackbuffer,$Width,$Height,$Mouse[0],$Mouse[1],$hPen);~ EndIf
[/autoit] [autoit][/autoit] [autoit]_GDIPlus_GraphicsDrawImageRect($hBackbuffer,$hFGBitmap,0,0,$Width,$Height)
[/autoit] [autoit][/autoit] [autoit]
_GDIPlus_GraphicsDrawImageRect($hGraphics,$hBitmap,0,0,$Width,$Height)
WEndFunc _Exit()
[/autoit]
_GDIPlus_Shutdown()
Exit
EndFunc -
Hi zusammen,
dass der Lock/Unlock ziemlich viel Zeit verbraucht, hatte ich schon bei anderen Aufgaben bemerkt. Leider ist mir bisher keine andere Variante untergekommen, um den Pointer auf die Bitmapdaten zu bekommen. Ich hatte schon daran gedacht, das "Handle" auseinanderzuklabustern. Ein Handle ist ja nichts weiter als ein Zeiger auf einen Speicherbereich mit Informationen. Irgendwo in diesem Speicherbereich muss zwangsläufig auch die Adresse der Bitmap stehen. Wenn da jemand bissl Zeit in reverse engeneering investieren würde, wäre das sehr zu begrüssen
name22
hast du schon versucht, die Bitmaps zu blitten? Das ist idR ziemlich schnell, mit etwas Glück unterstützt der Treiber der Graka das Blitten. -
-
Zitat
au man, was ist denn mit euch los ? oder macht ihr alles späße ?
Völliger Ernst das alles ist, junger Padawan!
Zitatund entdecke dass es einen "echten" kompiler für AutoIt Skripte gibt der automatisch alle Variablen richtig deklariert und castet und eine richtig "echte" asm-Exe daraus macht. xD
Naja, eine "richtige" Exe hat man doch heute schon. Das Argument der Größe lasse ich nur in absoluten Ausnahmefällen gelten, wenn das so wichtig wäre, gäbe es wesentlich mehr *.COM-Dateien
ZitatC++ Code.
Der wird dann Kompiliert.Kompilieren kann man jeden Code, das ist nicht das Ding! Aber so zu kompilieren, dass es JEDER Anforderung gerecht wird, ist das Problem! Genaue Berechnung oder schnelle Berechnung bissl schnell oder ungenaue Berechnung und ganz schnell?
C++ ist da ein hervorragendes Beispiel! Da wird lauthals die Portabilität hervorgehoben, aber wenn es "wirklich" mal drauf ankommt, kommt man nicht drumherum vom "Standard" abzuweichen, und auf für die jeweilige Plattform optimierte Libs einzusetzen. Und/oder hunderte Compilerschalter vorzusehen, die auch noch grösstenteils voneinander abhängig sind und jeweils andere Ergebnisse produzieren...Da bleibe ich lieber bei meinem AutoIt-Spaghetticode, undeklarierten Variablen unbestimmten Typs und "eingeschränkter" Geschwindigkeit, die übrigens in 99% aller Fälle völlig ausreiched ist. Ich bin Techniker, kein Programmierer. Das Ergebnis zählt. Und Leistung = Arbeit pro Zeit. In 15 Minuten ein "Script" incl benutzbarer Oberfläche erstellen zu können, welches mir und meinen Mitarbeitern die Arbeit erleichtert, ist m.E. mehr Wert als "Portabilität".
ZitatWas auch gehen müsste was Java (auch wenn ich es persönlich nicht mag ) uns vorgemacht hat:
Einen Installierbaren Interpreter der wesentlich schneller interpretieren kann als der Jetzige von AutoIt.Zieh mal 2000 Programmierer von Sun ab, in ca 10-15 Jahren hast du dann auch ein "schnelles" AutoIt
Nein, mal im Ernst, Java ist der Weg, und auch an der Idee von .Net ist was dran. Anders ist wirkliche Portabilität nicht machbar. Und das ist gut so! Aber Moment, irgendeiner hat doch was von Dateigrösse gesagt
.... -
Zitat
Andy: Man, jetzt hast du die ganze Verschwörungstheorie widerlegt.
nöööö, das war doch nur ein kleiner Stupser in die Richtung, wie man dieses Logo aus dem "Memory" (sic) extrahieren und anzeigen könnte.
Kürzestes Script gewinnt!
-
....oder einfach nur das(die) Logo-Icons in einem 16(32)-Bit-Farbformat....
Irgendwo müssen diese Dinger ja herkommen, oder hat sich bisher noch keiner gefragt, woher das Icon kommt, dass nach einem herzhaften Hieb auf F5 unten in der Taskleiste steht?
Bitmap-Format FTW
-
-
Hi,
ZitatHast du schon das Scrollen innerhalb von Browsern realisiert?!?
In den ersten hier geposteten Versionen war es noch enthalten, ich hatte es rausgenommen weil ich es a) den Browsergame-Fernsteuerungen nicht allzuleicht machen wollte
, und b) die Abfrage "Seitenende" nicht besonders zuverlässig in allen Fällen funktionierte (bei allen Browsern). ZitatWeil bei meiner XP Maschiene muss ich immer manuell innberhalb der Seite einen Scroller nach unten verschieben bevor der zu klickende Button sichtbar wird.
Simple Lösung: ein SEND pgdn, nachdem das Browserfenster mit der neuen Seite geöffnet wurde
Ich hatte schon mit div. Scroll-udf´s herumexperimentiert, wie gesagt, Browser sind da manchmal bissl eigen...besonders mit der Rückmeldung, ob das pgdn ausgeführt wurde. Man könnte natürlich abfragen, ob sich der Seiteninhalt geändert hat
.Allerdings sind meine Anwendungen noch nicht zeitkritisch, solange das Programm schneller ist als jeder Mensch der im 3-Schichtbetrieb 8h lang auf den Monitor stiert, habe ich keinen Handlungsbedarf.
ZitatUnd ist es so richtig das ich immer '_GDIPlus_Startup' und '_GDIPlus_Shutdown' Manuell ausführen muss,
Die Beispiele sollten alle laufen, ich habe hier schon lange nicht mehr geupdatet, der "Bedarf" scheint nicht sehr gross zu sein, wenn man nicht die gängigen "bösen" Begriffe in den Postings hier im Forum spammt

-
Hallo Webfish,
ZitatUmsatz Januar war 12.000
ist es richtig, dass du den fetten Teil des Textes suchst?
Wenn das so sein sollte, gibt es maximal 12 mögliche Suchstrings, nämlich die Monatsnamen.
Schau dir für diesen Fall mal das Programm PushTheButton an. Damit wäre es z.B.möglich, die 12 Texte "Umsatz war Januar","Umsatz war Februar" usw. von der Website einmalig "abzufotografieren", und diese gespeicherten Bilder dann automatisch auf der Website suchen zu lassen.
Die Suche gestaltet sich relativ zügig, die 12 Monatanamen sind auf einer Website incl. automatischem Scrollen im Browser in weniger als einer Sekunde gefunden./EDIT/ sry, hatte überlesen, dass der Text schon vorliegt
-
kurzes Beispiel, in der Console werden die Millisekunden ausgegeben
Spoiler anzeigen
[autoit]#include<date.au3>
[/autoit] [autoit][/autoit] [autoit]
#include <GUIConstantsEx.au3>
;timertestglobal $t=timerinit(),$sec=0
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]$hgui=guicreate("timer",200,50)
[/autoit] [autoit][/autoit] [autoit]
$label=GUICtrlCreateLabel("",20,20,200,30)
GUISetState()adlibregister("Millisekunde",1) ;theoretisch jede Millisekunde aufrufen
[/autoit] [autoit][/autoit] [autoit]while GUIGetMsg()<>-3
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
wendfunc Millisekunde();praktischer Aufruf alle x Millisekunden
[/autoit]
$time=_nowtime()
consolewrite($time&" : "&int(timerdiff($t))&@crlf)
GUICtrlSetData($label,$time&" : "&int(timerdiff($t)))
if stringright($time,1)<>$sec Then
$t=timerinit()
$sec=stringright($time,1)
endif
endfunc -
Hallo!
ZitatIch versuche so eine Uhr wo immer 1000 mikrosekunden dazu gerechnet werden.
Genau das ist das wo für ich hilfe brauch. Ich verstehe nicht wie man die Aktuellezeit in Mikrosekunden umrechnet.Um die Mikrosekunden zu errechnen, teilt man einfach die ermittelten Sekunden durch 1000000.
[autoit]
Die Frage ist allerdings, ob du es schaffst, jede Mikrosekunde auch anzeigen zu lassen!
Also einen Timer, der jede Sekunde in 1000000 Teile teilt und diese dann innerhalb dieser Sekunde hochzählt.
Viel Spass dabei!
Das Problem dabei ist, dass das Betriebssystem dir dein Programm regelmäßig unterbricht, um auch andere Programme "gleichzeitig" laufen zu lassen. Diese Unterbrechung wirft natürlich alles an genauer Berechnung im Mikrosekundenbereich über den Haufen.
Eine weitere Möglichkeit wäre, die Prozessor-Takte seit dem Rechnerstart abzufragen. Mit einer (internen) Umrechnung ist das genau das, wasTimerinit() Timerdiff()
[/autoit]machen. Aber einzelne Mikrosekunden einzufangen wirst du nicht schaffen....
1000 Mikrosekunden sind 1 Millisekunde, da sollte das wenigstens Ansatzweise möglich sein....
-
Um das abschliessend auch meinerseits mal klarzustellen, die Frage lautete:"Kann man bei ImageSearch auch Bilder mit unsichtbarem Background benutzen?"
Genau diese Frage wurde bereits gefühlte 12 Millionen Mal sowohl in diesem Forum, als auch im "bösen" Botforum, im englischen und im französischen Forum gestellt und dort auch beantwortet.
Aus diesem Grund auch mein Hinweis mit der erlesenen Gesellschaft in der du dich befindest. Anderen geht es genauso!
Natürlich ist mir klar, dass jemand bevor er hier einen Thread erstellt, zunächst die Suchfunktion der Foren und auch die Tante Google bemüht. Ich gehe also davon aus, dass du geflissentlich sämtliche dort gefundenen Hinweise und Lösungsvorschläge einfach ignorierst.Somit wäre eigentlich die passende Antwort auf "Kann man bei ImageSearch auch Bilder mit unsichtbarem Background benutzen?", ein einfaches "JA!" gewesen. Wäre damit dein Problem gelöst gewesen?! Offensichtlich nicht.
-
Kurzes Beispiel, wie exterm SSE die Geschwindigkeit beeinflussen kann!
Spoiler anzeigen
[autoit];Übersetzung FORTRAN => AutoIt by Andy
[/autoit] [autoit][/autoit] [autoit]
;Verfahren: http://www.unet.univie.ac.at/~a8727063/Science/BBP/
;
;Beispiele in FORTRAN;
;http://www.unet.univie.ac.at/~a8727063/Science/BBP/bbp.f90 bzw.
;http://www.unet.univie.ac.at/~a8727063/Science/BBP/bbpI2R4.f90
;
;errechnet die n-te Dezimalstelle von PI als HEX-Ziffer
;vgl. Tabelle der Ziffern bis 5000
;http://books.google.de/books?id=mchJC…tabelle&f=false#include<assembleit.au3>
[/autoit] [autoit][/autoit] [autoit]
#include <Array.au3>Dim $arrC[4] = [4, -2, -1, -1]
[/autoit] [autoit][/autoit] [autoit]
Dim $arr1[4]
Dim $arr2[4]
Dim $arr3[4]
Dim $arr4[4]Global $time, $k
[/autoit] [autoit][/autoit] [autoit]$log2 = Log(2)
[/autoit] [autoit][/autoit] [autoit]
$log16 = Log(2.0) * 4$err = 5 * 10 ^ - 32
[/autoit] [autoit][/autoit] [autoit]
$nmax = Int((Sqrt(2 ^ 63) - 5) /
;ohne _MemVirtualAlloc() kein align!
[/autoit] [autoit][/autoit] [autoit]
;align 16 in der dllstruct() funktioniert NICHT zuverlässig!
$pRemoteCode = _MemVirtualAlloc(0, 512, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE)
$struct = DllStructCreate("" & _ ;adresse in der struct
"float arr1[4];" & _ ;edi+00 xmm7=4,4,4,4
"float arr2[4];" & _ ;edi+16 xmm6=1,1,1,1
"float arr3[4];" & _ ;edi+32 xmm3=0,0,0,0
"float arr4[4];" & _ ;edi+48
"float arr5[4];" & _ ;edi+64 xmm5=1,4,5,6
"float nullfuenf;" & _ ;edi+80
"float log2" & _ ;edi+84
"int", $pRemoteCode) ;edi+88 speicherplatz div zwischenwerte
$ptr = DllStructGetPtr($struct)
For $i = 1 To 4
DllStructSetData($struct, 1, 4.0, $i);xmm7=4,4,4,4
DllStructSetData($struct, 2, 1.0, $i);xmm6=1,1,1,1
DllStructSetData($struct, 3, 0.0, $i);xmm3=0,0,0,0
Next
DllStructSetData($struct, 5, 1.0, 1);xmm5=1
DllStructSetData($struct, 5, 4.0, 2);xmm5=1,4
DllStructSetData($struct, 5, 5.0, 3);xmm5=1,4,5
DllStructSetData($struct, 5, 6.0, 4);xmm5=1,4,5,6DllStructSetData($struct, 6, 0.5, 1);0.5
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
DllStructSetData($struct, 7, $log2, 1);log2Func _pi_hex()
[/autoit] [autoit][/autoit] [autoit]
_("use32")
_("finit") ;copro -init
_("mov edi,[esp+4]") ;startadresse struct holen_("movaps xmm7,[edi+00]") ;arr1=4,4,4,4
[/autoit] [autoit][/autoit] [autoit]
_("movaps xmm6,[edi+16]") ;arr2=1,1,1,1
_("movaps xmm3,[edi+32]") ;arr3
_("movaps xmm5,[edi+64]") ;arr5=1,4,5,6_("mov ebx,-1") ;zähler K
[/autoit] [autoit][/autoit] [autoit]
_("_for_k:")
_("add ebx,1")_("cmp ebx,[esp+8]") ;vgl k mit N
[/autoit] [autoit][/autoit] [autoit]
_("ja _ende") ;wenn fertig, ende_("mov edx,[esp+8]") ;l=n
[/autoit] [autoit][/autoit] [autoit]
_("sub edx,ebx") ;l=n-k_("movaps xmm1,xmm7") ;arr1=4,4,4,4
[/autoit] [autoit][/autoit] [autoit]
_("movaps xmm2,xmm6") ;arr2=1,1,1,1
;arr4=1+k+8 , 4+k*8 , 5+k*8 , 6+k*8
_("mov eax,ebx") ;k
_("shl eax,3") ;k*8 20
_("mov [edi+48],eax") ;arr4=0 , k*8 , 0 , 0
_("mov [edi+56],eax") ;arr4=0 , k*8 , 0 , k*8
_("movsldup xmm4,[edi+48]") ;arr4=k*8 , k*8 , k*8 , k*8
_("cvtdq2ps xmm4,xmm4") ;arr4 float( aus allen 4 integer)
_("addps xmm4,xmm5") ;arr4=1+k*8,4+k*8,5+k*8,6+k*8_("cmp edx,0") ;ist L=0?
[/autoit] [autoit][/autoit] [autoit]
_("je _arr3") ;ja, dann arr3:
_("")
;int(log(L+0.5)/log2) ;folgende zeilen stark kürzbar
_("mov [edi+88],edx") ;L
_("emms") ;fpu und sse zusammen braucht emms!
_("fld dword[edi+80]") ;st0=0.5
_("fld dword[edi+84]") ;st0=log2 st1=0.5
_("fldln2") ;st0=ln2 st1=log2 st2=0.5
_("fild dword[edi+88]") ;st0=L st1=1 st2=log2 st3=0.5
_("fadd st0,st3") ;st0=L+0.5 st1=1 st2=log2 st3=0.5
_("fyl2x") ;st0=ln2*log_2(L+0.5) st1=log2 st2=0.5 32550
_("fdiv st0,st1") ;st0=(ln2*log_2(L+0.5)/log2) st1=log2 st2=0.5
_("fisttp dword[edi+88]") ;st0=log2 st1=0.5
_("fucompp") ;fpu-stack cleanen_("mov esi,-1")
[/autoit] [autoit][/autoit] [autoit]
_("_for_i:")
_("add esi,1")
_("cmp esi,[edi+88]") ;ist i=int(log(L+0.5)/log2) ?
_("ja _arr3")
_("")
;arr1=mod(arr1^2,arr4) für alle 4 floats_("mulps xmm1,xmm1") ;arr1^2
[/autoit] [autoit][/autoit] [autoit]
_("movaps xmm0,xmm1") ;arr1^2
;;berechnet mod=rest=a-int(a/b)*b
_("divps xmm0,xmm4") ;a/b
_("cvttps2dq xmm0,xmm0") ;int(a/b)
_("cvtdq2ps xmm0,xmm0") ;float(int(a/b))
_("mulps xmm0,xmm4") ;int(a/b)*b
_("subps xmm1,xmm0") ;arr1=mod(arr1^2,arr4) für alle 4 floats ;
_("")
_("bt edx,esi") ;bit_test(L,I)
_("jnc _for_i")
_("")
;arr2=mod(arr2*arr1,arr4)
_("mulps xmm2,xmm1") ;arr2*arr1
_("movaps xmm0,xmm2") ;arr2*arr1
;;berechnet rest=a-int(a/b)*b
_("divps xmm0,xmm4") ;a/b
_("cvttps2dq xmm0,xmm0") ;int(a/b)
_("cvtdq2ps xmm0,xmm0") ;float(int(a/b))
_("mulps xmm0,xmm4") ;int(a/b)*b
_("subps xmm2,xmm0") ;arr2=mod(arr2*arr1,arr4) für alle 4 floats_("jmp _for_i")
[/autoit] [autoit][/autoit] [autoit]_("_arr3:")
[/autoit] [autoit][/autoit] [autoit]
_("movaps xmm0,xmm2") ;arr2
_("divps xmm0,xmm4") ;arr2/arr4
_("addps xmm3,xmm0") ;arr3+arr2/arr4
_("movaps xmm0,xmm3") ;arr3+arr2/arr4
;;berechnet rest=a-int(a/b)*b
_("divps xmm0,xmm6") ;a/b
_("cvttps2dq xmm0,xmm0") ;int(a/b)
_("cvtdq2ps xmm0,xmm0") ;float(int(a/b))
_("mulps xmm0,xmm6") ;int(a/b)*b
_("subps xmm3,xmm0") ;arr3=mod(arr3+arr2/arr4,arr6) für alle 4 floats
_("jmp _for_k")_("_ende:")
[/autoit] [autoit][/autoit] [autoit]
_("movaps [edi],xmm3") ;xmm3 ins erste feld der struct schreiben
_("movaps [edi+48],xmm4");xmm3 ins erste feld der struct schreiben
_("mov eax,edx") ;L return
_("ret")
_("")EndFunc ;==>_pi_hex
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]While 1
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
$n = InputBox("n-te Stelle von PI", "Gesuchte Ziffer eingeben max=" & $nmax)
If $n <= 0 Or $n > $nmax Then Exit
For $i = 1 To 4 ;struct füllen für den Assemblerteil
DllStructSetData($struct, 1, 4.0, $i);xmm7=4,4,4,4
DllStructSetData($struct, 2, 1.0, $i);xmm6=1,1,1,1
DllStructSetData($struct, 3, 0.0, $i);xmm3=0,0,0,0
Next;der Assemblerteil ersetzt die Hauptschleife For K=0 to N
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
;folgende 2 Zeilen gehören an den Anfang des ScriptsGlobal $tCodeBuffer = DllStructCreate("byte[213]") ;reserve Memory for opcodes
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
DllStructSetData($tCodeBuffer, 1, "0x9BDBE38B7C24040F283F0F2877100F285F200F286F40BBFFFFFFFF83C3013B5C24080F87A30000008B54240829DA0F28CF0F28D689D8C1E003894730894738F30F1267300F5BE40F58E583FA00745B8957580F77D94750D94754D9EDDB4758D8C3D9F1D8F1DB4F58DAE9BEFFFFFFFF83C6013B775877330F59C90F28C10F5EC4F30F5BC00F5BC00F59C40F5CC80FA3F273DD0F59D10F28C20F5EC4F30F5BC00F5BC00F59C40F5CD0EBC50F28C20F5EC40F58D80F28C30F5EC6F30F5BC00F5BC00F59C60F5CD8E950FFFFFF0F291F0F29673089D0C3") ;write opcodes into memory$flag = 1 ;wenn 0, dann AssembleIt()
[/autoit] [autoit][/autoit] [autoit]If $flag Then ;CallWindowProcW
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
$t = TimerInit()
$ret = DllCall("user32.dll", "int", "CallWindowProcW", "ptr", DllStructGetPtr($tCodeBuffer), "ptr", $ptr, "int", $n, "int", 0, "int", 0)
$m = TimerDiff($t)
$l = $ret[0]
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $m = ' & $m & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
Else
;$_assembleit_flag=0 ;um opcodes aus dem Assemblercode zu erstellen
$t = TimerInit()
$l = _AssembleIt("int", "_pi_hex", "ptr", $ptr, "int", $n)
$m = TimerDiff($t)
;$l = $ret[0]
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $m = ' & $m & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
EndIf;Auswertung:
[/autoit] [autoit][/autoit] [autoit]
For $i = 1 To 4 ;array aus der struct füllen
$arr3[$i - 1] = DllStructGetData($struct, 1, $i)
$arr4[$i - 1] = DllStructGetData($struct, 4, $i)
Next$fsum = _modulo(_dot_product($arrC, $arr3), 1.0)
[/autoit] [autoit][/autoit] [autoit]Dim $asum[4]
[/autoit] [autoit][/autoit] [autoit]
$asum[0] = $arrC[0] / ($arr4[0] +
$asum[1] = $arrC[1] / ($arr4[1] +
$asum[2] = $arrC[2] / ($arr4[2] +
$asum[3] = $arrC[3] / ($arr4[3] +
$cor = _sum($asum) / 16
[/autoit] [autoit][/autoit] [autoit]
$ester = $k * $err
$string = ""
For $i = 2 To Int(-Log($cor) / $log16)
If $i = $l Then $string &= "( "
$fsum = 16 * Mod($fsum, 1.0)
$string &= Hex(Int($fsum), 1) & " "
Next
If $i > $l And StringInStr($string, "(") Then $string &= ")"MsgBox(0, $n + 1 & " -te hex-ziffer von Pi =", Hex(Int(16 * _Modulo(_dot_product($arrC, $arr3), 1.0)), 1) & @CRLF & @CRLF & "nächste Ziffern (incl.) = " & $string)
[/autoit] [autoit][/autoit] [autoit]WEnd
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]Func _akt()
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
ConsoleWrite('timerdiff($time) = ' & Int((TimerDiff($time) + 1) / 1000) & " k= " & $k & @CRLF) ;### Debug Console
EndFunc ;==>_aktFunc _dot_product($a, $b)
[/autoit] [autoit][/autoit] [autoit]
$vec = 0
For $i = 0 To UBound($a) - 1
$vec += $a[$i] * $b[$i]
NextReturn $vec
[/autoit] [autoit][/autoit] [autoit]
EndFunc ;==>_dot_productFunc _btest($a, $pos) ;bittest liefert TRUE, wenn das ($pos-te Bit von $a) = 1 ist
[/autoit] [autoit][/autoit] [autoit]
;http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gfortran/BTEST.html
$bit = BitAND(2 ^ 31 - 1, 2 ^ $pos)
If BitAND($a, $bit) Then
Return True
Else
Return False
EndIfEndFunc ;==>_btest
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]Func _modulo($a, $b) ;ir1 - floor(ir1/ir2)*ir2
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
;http://de.wikibooks.org/wiki/Fortran:_…nktionen#Modulo
Return $a - Floor($a / $b) * $b
EndFunc ;==>_moduloFunc _sum($e)
[/autoit]
$sum = 0
For $i = 0 To UBound($e) - 1
$sum += $e[$i]
Next
Return $sum
EndFunc ;==>_sum
Leider gibt es einen kleinen Pferdefuss, den ich bisher noch nicht lokalisieren konnte.
Die hex-Ziffern werden leider nur bis zur ca. 550. Stelle richtig berechnet. Ab der 550. Stelle schleicht sich ein minimaler Fehler ein, der dazu führt, dass die folgenden Ergebnisse falsch werden.
Ob das schon mit dem einfachen float-Format (32bit) zu tun hat, werde ich untersuchen.Jedenfalls ist die Geschwindigkeit sagenhaft, da ein komplettes $Array[4] in einem XMM-Register Platz hat und so alle Berechnungen für jeden Teilnehmer im Array durchgeführt werden.
bsp Multiplikation zweier Arrays $a[4] und $b[4]:
$a[0]=$a[0]*$b[0]
$a[1]=$a[1]*$b[1]
$a[2]=$a[2]*$b[2]
$a[3]=$a[3]*$b[3]
wird zu
mulps xmm0,xmm1 ;jeweils gefüllt mit 4 floats
und das wird in einer Handvoll Takte berechnet.Die millionste Stelle wird vom Script so in weit unter einer Sekunde ermittelt! Wobei man fairerweise zugeben muss, dass ab der ca. 5000. Stelle die Genauigkeit der floats sowieso nicht mehr ausreichend ist. Vielleicht weite ich das Script ja noch auf 64Bit Genauigkeit aus.....schaumamal^^
-
Man merkt mal wieder deutlich das geistige Defizit bei der Problembeschreibung! Aber tröste dich, du befindest dich in erlesenster Gesellschaft!
Um mal den "Apparat", der sich idR zwischen den Ohren befinden sollte, bissl anzutreiben:
Wer zwingt dich denn, mehr an Daten (Pixel) abzufragen, als du eigentlich brauchst?Um mal bei deinem Beispielicon Trashbin mit transparentem "Hintergrund" zu bleiben, wo ist das Problem nur die Pixel zu suchen, die NICHT transparent sind?
Bei mehrteiligen, weil durch transparente Flächen unterbrochenen Suchmasken, macht man halt mehrere "kleine" Abfragen!
Das bedeutet natürlich Aufwand und vor allem Knowhow!Mit PushTheButton (such mal danach hier im Forum) finde ich im täglichen Einsatz sogar bewegte Bilder mit transparentem Hintergrund. Imagesearch kann das mit Sicherheit auch!
Auf eine C&P-"Lösung" musst du allerdings lange warten....