PDA

View Full Version : Dint Vorzeichen immer minus einstellen



bludie
17.06.2010, 08:22
Hallo Leute,
ich würde gerne bei einem Dint-Wert immer das Vorzeichen auf minus einstellen. Egal ob dieser schon auf minus steht oder nicht.
Allerdings habe ich für den benötigten Programmcode nicht das Wissen des Befehlsvorrats.
Sicherlich wisst ihr hierfür eine Lösung.
Gruß bludie

Larry Laffer
17.06.2010, 08:33
Hallo,
einfach per Vergleich überprüfen, ob die Zahl kleiner 0 ist. Wenn ja, dann nichts machen, wenn nein, dann mit -1 multiplizieren ...

Gruß
LL

rostiger Nagel
17.06.2010, 08:34
bei den Zahlenformat DINT kannst du das höchste Bit 2^31 immer auf "1"
setzen, das könnte vlt wie folgt aussehen. Der wert 8000 0000 hex ist das
Vorzeichen Bit und wird einfach mit deiner Var "oder" genommen und deiner
Variabel zurückgeschrieben.




L "Variabel"
L DW#16#8000 0000
OD
T "Variabel"

Bienenkoenig
17.06.2010, 08:34
Hi,
auf kleiner 0 abfragen, sonst mit -1 multiplizieren

Gruß
Bienenkönig

Larry Laffer
17.06.2010, 08:42
@Helmut:
ich bin mit deiner Lösung nicht so recht einverstanden.
Vergleich doch im Hex-Format mal den Wert von 1 und -1 - der Unterschied ist dabei NICHT das Vorzeichenbit ...

Gruß
LL

PN/DP
17.06.2010, 08:45
@Helmut: einfach das Vorzeichen-Bit setzen ist nicht korrekt.

So wird's was (optimierter Code):

L MD 100
NEGD // * -1
SPMZ M001 // wenn jetzt negativ oder 0 -> dann übernehmen
NEGD // war jetzt positiv -> nochmal * -1
M001: T MD 100

Gruß
Harald

Rainer Hönle
17.06.2010, 08:47
@Helmut
Das oberste Bit ist schon das Vorzeichenbit. Nur werden die Zahlen nicht einfach mit dem gesetzten Bit sondern als Zweierkomplement dargestellt. -1 entspricht dabei 0xFFFFFFFF, -2 entspricht 0xFFFFFFFE etc.
Das Zwierkomplement bekommst Du durch negieren aller Bits und addieren von 1
Beispiel:
Ausgang 0x00000001
Negieren 0xFFFFFFFE
Addieren 0xFFFFFFFF

Guido
17.06.2010, 08:48
Hallo,

EDITIERT WEGEN FEHLER.

Guido

Perfektionist
17.06.2010, 09:08
@ Harald: sehr hübsch! Ich wäre nie auf die Idee gekommen, das Vorzeichen mit dem NEGD-Befehl zu ermitteln. Bravo!

PN/DP
17.06.2010, 09:27
Ich wäre nie auf die Idee gekommen, das Vorzeichen mit dem NEGD-Befehl zu ermitteln.
Als alter Z80- und 80x86-Assembler-Programmierer bin ich es gewohnt mit möglichst wenig Akku-Registern auszukommen.
Deshalb arbeite ich auch gern mit den Statusbits als Operations-Ergebnis statt zusätzliche Vergleiche anzustellen.
Extra eine 0 zu laden und dann zu vergleichen ist mir für diese Aufgabe zu langweilig. ;)

Gruß
Harald

bludie
17.06.2010, 10:10
Hallo,
erst mal ein dickes Lob an das Forum. So schnelle Hilfe hatte ich gar nicht erwartet.
@Harald
Super einfacher Code. Funzt bestens.

Perfektionist
17.06.2010, 10:16
Als alter Z80- und 80x86-Assembler-Programmierer ...insofern bin ich von dem 6502 sehr verwöhnt worden. Der hat die Flags bereits beim Ladebefehl gesetzt.
http://www.htu.tugraz.at/~herwig/6502/lda.php
Als ich dann mit der 80er-Welt in Berührung kam, war das natürlich erstmal lästig, dass diese Prozessoren in dieser Hinsicht recht faul waren. Gut - ich hab mich daran gewöhnt. Und hätte hinter dem NEGD-Befehl halt nicht vermutet, dass der die Flags beeinflusst. Aber klar - NEGD wirft die ALU an, so wie OD z.B. auch. Und das geht auf die Flags (Statuswort).

PN/DP
17.06.2010, 10:33
Hallo bludie,

auch wenn es LL nicht gern sieht, daß gleich die Komplett-Lösung geantwortet wird ;)
hier mal zum Vergleich die verstehbare Programmlösung für Deine Aufgabe (so wie von LL und Bienenkönig empfohlen):


// V2: normal verständlicher Programmcode:
L MD 100
L 0 // (exakt wäre "L L#0", ist aber länger)
<=D // ist MD100 schon negativ oder 0 ?
SPB M002 // ja -> kann so bleiben
POP // nein -> MD100 zurück in AKKU1 (TAK geht auch)
NEGD // * -1
T MD 100 // MD100 mit -(MD100) überschreiben
M002: NOP 0

// V3: 1 Operation kürzer:
L 0
L MD 100
>=D // ist MD100 schon negativ oder 0 ?
SPB M003 // ja -> kann so bleiben
NEGD // nein -> * -1
T MD 100 // MD100 mit -(MD100) überschreiben
M003: NOP 0

// will man den Programmablauf genau beobachten,
// dann das "NOP 0" durch "L MD100" (oder "T MD100") ersetzen

Welche Variante gefällt Dir nun am Besten?
(EDIT: ich sehe schon: die erste "Super einfache" kommt gut an)


insofern bin ich von dem 6502 sehr verwöhnt worden. Der hat die Flags bereits beim Ladebefehl gesetzt.
Ja, das wäre perfekt, wenn der S7-Akku das auch täte.
Immer diese "überflüssigen" Befehle, nur damit die Flags auswertbar werden ...

Gruß
Harald

Larry Laffer
17.06.2010, 11:26
auch wenn es LL nicht gern sieht, daß gleich die Komplett-Lösung geantwortet wird ;)

Nan-na Harald,
so schlimm bin ich doch auch nicht.
In dem fall kann man m.E. schon die Komplett-Lösung liefern. Für mich erschien es nur einfacher, das zu beschreiben als den Code hier einzustellen ... ;)
Dein Code-Beispiel fand ich übrigens auch gut - es ist ja um Einiges einfacher :)

Gruß
LL

PN/DP
17.06.2010, 18:42
Wenn schon der Perfektionist hier reinschaut, dann will ich zugeben, daß mein Programmcode
aus #6 doch tatsächlich noch verbessert werden kann: ;)


// V4: schnellere Variante:

L MD 100
NEGD // * -1
SPPZ M004 // wenn jetzt >= 0 -> dann nichts tun
T MD 100 // ist jetzt negativ -> übernehmen
M004: NOP 0

Dieser Code dürfte auf S7-300 ca. 0,1µs schneller sein und beschreibt MD100 nur wenn nötig.

MD100 kann vor diesem Programmstück nur positiv sein, wenn er irgendwo geändert wird.
In den allermeisten Zyklen muß die CPU bei meinem Programmcode in #6 1x NEGD und 1x T MD100
überflüssigerweise ausführen (muß also alle 5 Operationen ausführen).
Nun müssen meistens nur noch 3 Operationen ausgeführt werden (das NOP nicht mitgerechnet).

Gruß
Harald

rostiger Nagel
17.06.2010, 18:59
Wenn schon der Perfektionist hier reinschaut, dann will ich zugeben, daß mein Programmcode
aus #6 doch tatsächlich noch verbessert werden kann: ;)


// V4: schnellere Variante:

L MD 100
NEGD // * -1
SPPZ M004 // wenn jetzt >= 0 -> dann nichts tun
T MD 100 // ist jetzt negativ -> übernehmen
M004: NOP 0

Dieser Code dürfte auf S7-300 ca. 0,1µs schneller sein und beschreibt MD100 nur wenn nötig.

MD100 kann vor diesem Programmstück nur positiv sein, wenn er irgendwo geändert wird.
In den allermeisten Zyklen muß die CPU bei meinem Programmcode in #6 1x NEGD und 1x T MD100
überflüssigerweise ausführen (muß also alle 5 Operationen ausführen).
Nun müssen meistens nur noch 3 Operationen ausgeführt werden (das NOP nicht mitgerechnet).

Gruß
Harald

harald,
das ist Perfekt, ich denke sogar für den Perfektionisten :icon_mrgreen:

Heute wieder einiges gelernt :D

vierlagig
17.06.2010, 19:06
// V4: schnellere Variante:

L MD 100
NEGD // * -1
SPPZ M004 // wenn jetzt >= 0 -> dann nichts tun
T MD 100 // ist jetzt negativ -> übernehmen
M004: NOP 0


aber warum negieren, wenn schon negativ?



L MD 100
SPMZ M004
NEGD
M004: T MD 100

rostiger Nagel
17.06.2010, 19:08
Wenn das so weiter geht, können Siemens ihre CPU's wieder langsamer
machen :icon_mrgreen:

Perfektionist
17.06.2010, 20:21
aber warum negieren, wenn schon negativ?



L MD 100
SPMZ M004
NEGD
M004: T MD 100
Hallo 4L,
wenn ich jetzt (zu vorgerückter Stunde) S7 griffbereit hätte, würde ich jetzt zunächst die Hilfe zum Lade-Befehl bemühen. Ich bin mir aber dennoch zu 99% sicher, dass bei S7 der Ladebefehl nicht die Flags (Statuswort) beeinflusst. Ich befürchte, der SPMZ wird nicht Rücksicht auf den Wert in MD100 nehmen.

vierlagig
17.06.2010, 20:31
Hallo 4L,
wenn ich jetzt (zu vorgerückter Stunde) S7 griffbereit hätte, würde ich jetzt zunächst die Hilfe zum Lade-Befehl bemühen. Ich bin mir aber dennoch zu 99% sicher, dass bei S7 der Ladebefehl nicht die Flags (Statuswort) beeinflusst. Ich befürchte, der SPMZ wird nicht Rücksicht auf den Wert in MD100 nehmen.

hab es ebenso wenig griffbereit, aber die OP-liste und natürlich hast du recht, leider ... aber man wird doch mal träumen dürfen :rolleyes:

Flinn
17.06.2010, 20:40
Hier ein 6-Zeiler, wenn auch nicht so optimal (Zahlenbereich, Laufzeit) wie die obigen Lösungen, aber mal was anderes:



L MD100
DTR
ABS
NEGR
RND
T MD100


Gruß
Flinn

vierlagig
17.06.2010, 20:50
"NEGR sa ma nich mehr ... wieviele da verrecken is uns scheiß egal, aber neger sagen wir nich mehr ... da sind wir politisch korrekt" ... volker pispers :icon_mrgreen:

Perfektionist
17.06.2010, 21:13
@Flinn: wenn ich in DINT rechne, dann gibt es gute Gründe dafür. Ansonsten: bitte die Daten gleich in Real ablegen. Es ergibt keinen Sinn, Daten in DINT zu halten, die Berechnungen aber in REAL durchzuführen. Entweder, ich rechne REAL und halte die Daten in REAL, oder ich rechne in DINT und halte die Daten in DINT. Einzige Ausnahme (bei mir): ich benötige bisweilen eine Wurzelfunktion. Diese habe ich in der Vergangenheit tatsächlich mit einer Genauigkeit von nur acht Bit mittels einer Tabelle berechnet, weil dies die laufzeiteffizienteste Variante bei lahmen 300er-CPUs war. Hier greife ich seit CPU 317/319 neuerdings tatsächlich zur REAL-Arithmetik. Aber nur deshalb, weil es nicht genauer als 24 Bit sein muss und diese neueren CPUs dies genausoschnell erledigen, wie der alte (und bewährte) Algorithmus mit dem Tabellenzugriff.

PN/DP
18.06.2010, 00:49
Ich befürchte, der SPMZ wird nicht Rücksicht auf den Wert in MD100 nehmen.
Hmmm, wenn mir doch auch mal so ein genialer Satz einfallen würde! :cool:

Ich kann leider nur sowas technisches:

einfach das Vorzeichen-Bit setzen ist nicht korrekt.

Naja, vielleicht lerne ich hier im Forum noch etwas Diplomatie. ;)

Gruß
Harald

ssound1de
18.06.2010, 05:02
aber warum negieren, wenn schon negativ?



L MD 100
SPMZ M004
NEGD
M004: T MD 100


Super genial - wenn es denn funktionieren würde. :rolleyes:
Ist aber doch eher dem Zufall überlassen.
L MD 100 beeinflusst leider nicht die Statusbits A1/A0, weshalb der Sprung sich nicht die Mühe machen wird.