| |
|
|
| [quote:00a30dd46d=Michael Wodrich]Yo wußte doch, Yo el direkte Zugreifen en Double-Werte de Profano ya veces rausgetüftelt hatte....
Damit Yo el Función FindEdge() algo direkter programmiert. Diese Función es en el Original bajo el Beispielen como Fließkommazahlen.prf para encontrar.
Außerdem Yo mich veces a el Gegenstück a INT() intenta. Bajo Pascal heißt esta Función Frac().
Dieser Codeschnipsel es todavía con el MemoryModule-freien Versión de XPIA getestet worden - se ejecuta en me fehlerfrei.
Como fällt me una: se lo en XPIA ajustable ser, welche Variante uno einsetzt? Das Generieren uno externo DLL ha en efecto seine Vorteile - z.B. para ältere Profano-Versionen una DLL a redactar.
Hier el Code: KompilierenMarcaSeparación!
{$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 después de Tastendruck/Mausklick"
waitinput
end
Schöne Grüße Michael Wodrich[/quote:00a30dd46d] |
|
|
| |
|
|