| |
|
|
| [quote-part:00a30dd46d=Michael Wodrich]je wußte doch, qui je cela directe Zugreifen sur Double-Werte de Profan déjà la fois rausgetüftelt hatte....
avec cela habe je qui Funktion FindEdge() quelque chose direkter programmiert. cet Funktion ist im Original sous den Beispielen comme Fließkommazahlen.prf pour trouver.
Aussi habe je mich la fois à dem Gegenstück trop INT() versucht. sous Pascal est cet Funktion Frac().
cette Codeschnipsel ist encore avec qui MemoryModule-freien Version de XPIA getestet worden - fonctionne chez mir correct.
là fällt mir un: wird es dans XPIA einstellbar son, quelle variante on einsetzt? cela Generieren einer externe DLL hat oui aussi sa Vorteile - z.B. pour ältere Profan-Versionen une DLL trop erstellen.
ici qui Code: KompilierenMarqueSéparation!
{$cleq}
{$cliq}
Proc geaendertes_Beispiel
Sucht die höchste und die niedrigste Zahl aus einem Array mit Fließkommazahlen.
Declare anzahl&
Anzahl Fließkommazahlen im Array
anzahl& = 30
Declare Tabelle_1![anzahl&], Tabelle_2![2], x&, y&, z&, text$
Randomize
Zufällige Fließkommazahlen
generieren.
WhileLoop anzahl&
Tabelle_1![&loop - 1] = Rnd(100000) / 1.09 - 50000
EndWhile
Assemblerfunktions-Parameters: Adresse von Tabelle mit Floats, Adresse von Zieltabelle, Anzahl Floats
AsmStart FindEdge ( addr(Tabelle_1![0]), addr(Tabelle_2![0]), anzahl& )
Local tmp :REAL10
mov edx, para1
mov ebx, para2
mov ecx, para3
fld qword ptr [edx] ; st(3): min STK:(0:min)
fld qword ptr [edx] ; st(2): max STK:(0:max,1:min)
schleife:
fld qword ptr [edx] ; st(1): akt. Vergleichswert STK:(0:akt,1:max,2:min)
fld st(0) ; st(0) dupl. akt. Vergleichswert STK:(0:akt,1:akt,2:max,3:min)
fcomp st(3) ; cmp st0 < st3 ? (st0 wird geändert/entfernt) STK:(0:akt,1:max,2:min)
fnstsw ax
sahf
jae over1 ; überspringe wenn st0 >= st3
fst st(2) ; sichere neuen Minimumwert (derzeit st2) STK:(0:akt,1:max,2:neumin)
over1:
fld st(0) ; st(0) dupl. akt. Vergleichswert STK:(0:akt,1:akt,2:max,3:min)
fcomp st(2) ; cmp st0 > st2 ? (st0 wird geändert/entfernt) STK:(0:akt,1:max,2:min)
fnstsw ax
sahf
jbe over2 ; überspringe wenn st0 <= st2
fst st(1) ; sichere neuen Maximumwert (derzeit st1) STK:(0:akt,1:neumax,2:min)
over2:
fstp [tmp] ; entferne akt.Wert vom Stapel STK:(0:max,1:min)
add edx, 8 ; auf den nächsten double-Wert zeigen
sub ecx, 1 ; Countdown
jne schleife ; solange <> 0 : weitermachen
fstp qword ptr [ebx] ; Maximum sichern STK:(0:min)
fstp qword ptr [ebx+8] ; Minimum sichern STK:()
AsmEnd
--- kleiner Zusatz-Programmteil ---
Zahlen am Dezimalpunkt ausrichten
- zuerst den am weitesten rechts stehenden Dezimalpunkt feststellen
Declare Dezipunkt%, i%,tmp$, j%,tmp2$
WhileLoop anzahl&
tmp$ = Str$(Tabelle_1![&loop - 1])
i% = InStr(".",tmp$)
Case (i% = 0) : i% = Len(tmp$) + 1 dann stehen Integers vor dem Dezipunkt
Case (i% > Dezipunkt%) : Dezipunkt% = i%
EndWhile
Inc Dezipunkt% dadurch ist links mind. ein Leerzeichen
- dann die ausgerichtete Ausgabe
WhileLoop anzahl&
tmp$ = Str$(Tabelle_1![&loop - 1])
i% = InStr(".",tmp$)
If i% = 0
Print Space$(Dezipunkt% - Len(tmp$) - 1) + tmp$
Else
Print Space$(Dezipunkt% - i%) + tmp$
EndIf
EndWhile
- für die MinMax-Werte
tmp$ = Str$(Tabelle_2![0])
i% = InStr(".",tmp$)
tmp2$ = Str$(Tabelle_2![1])
j% = InStr(".",tmp2$)
Dezipunkt% = if(i% > j%,i%,j%) + 1
Print
Print "Höchste Zahl aus dem Array =", Space$(Dezipunkt% - i%) + tmp$
Print "Niedrigste Zahl aus den Array =", Space$(Dezipunkt% - j%) + tmp2$
EndProc
Proc Frac
Parameters value!
AsmStart Frac_asm ( Addr(value!) )
Local d1 :WORD
local d2:word
mov edx, para1
fnstcw [d1] ; fpu control word wegsichern
fwait ; warten
mov cx, [d1]
or cx, 0F00h ; Präzision/Rundung maskieren (keine Rundung)
mov [d2], cx ; Änderung nach d2
fldcw [d2] ; ...und in die fpu
fld qword ptr [edx] ; Wert laden
frndint ; runde Wert auf Ganzzahl (also abschneiden)
fld qword ptr [edx] ; Wert laden (st0=gesamtwert,st1=INT-Wert)
fsub st(0), st(1) ; value! - INT(value!)
fstp st(1) ; st0 nach st1 kopieren und st0 vom stack entfernen
fstp qword ptr [edx] ; jetzigen st0 nach value! speichern
fldcw [d1] ; fpu control word zurückladen
AsmEnd
Return value!
EndProc
Proc Ausgabe
Parameters d!
print "Wert.....: ", d!
print "gerundet.: ", Round( d!, 0 )
print "Ganzzahl.: ", Int( d! )
print "Nachkomma: ", Frac( d! )
EndProc
--- Main ---
set("decimals",15)
WindowTitle "Frac - anschließend geändertes Fließkommazahlen.prf"
Window 0,0 - %maxx,%maxy
Print
Print "Zeigt das Runden, den Vorkomma-Wert, und mittels Assembler den Nachkomma-Wert."
Print
Print "----------"
Ausgabe 5.6
Print "----------"
Ausgabe Pi()
Print "----------"
Print
Print "weiter mit Tastendruck/Mausklick"
Print
waitinput
WindowTitle "jetzt geändertes Fließkommazahlen.prf"
geaendertes_Beispiel
Print
Print "Dieses FindEdge findet Maximum und Minimum"
Print "in einem Array in nur einem Durchgang."
Print "Zur Zwischenspeicherung wird der FPU-Stack benutzt."
Print
Print "Zahlen werden am Dezimalpunkt ausgerichtet."
Print
Print &qu e pour Tastendruck/Mausklick"
waitinput
end
belle Grüße Michael Wodrich[/quote-part:00a30dd46d] |
|
|
| |
|
|