TIA UINT auf Größer vergleichen

Zuviel Werbung?
-> Hier kostenlos registrieren
Ja, vermutlich sieht man das zu recht selten, da vermutlich jeder zweite den Fehler machen würde:

Code:
L MD500 // DINT
L 1
+D
T MD500 // funktioniert

L MD500 // DINT
+ 1
T MD500 // funktioniert nicht

L MD500 // DINT
+ L#1
T MD500 // funktioniert

Gruß.

Ja, kleine Ursache große Wirkung ( die u.U. erst spät auffällt )
 
Wenn man sich mit den AWL-Befehlen nicht 100% auskennt dann schreibe lieber ausführlicher so wie AWL-Code aus FUP/KOP aussieht.
Fallstricke bei simpler Addition in AWL:
Code:
L   #diVar1   // 16#0000FFFF : (65535)
[COLOR="#FF0000"]+   1         // 16#00000000 : weil 16 Bit Addition! (nur AKKU1-L)[/COLOR]
T   #diVar2   // -> [COLOR="#FF0000"]0[/COLOR]

L   #diVar1   // 16#0000FFFF : (65535)
+   L#1       // 16#00010000 : weil 32 Bit Addition! (ganzer AKKU1)
T   #diCount  // -> 65536

L   #diVar1   // 16#0000FFFF : (65535)
[COLOR="#FF8C00"]L   1         // 16#00000001 : wird als 16-Bit-Wert geladen! AKKU1-H wird auf 0 gesetzt[/COLOR]
+D            // 16#00010000 : 32 Bit Addition - nochmal gut gegangen
T   #diCount  // -> 65536

L   #diVar1   // 16#0000FFFF : (65535)
L   L#1       // 16#00000001 : wird als 32-Bit-Wert geladen
+D            // 16#00010000 : 32 Bit Addition
T   #diCount  // -> 65536

L   #diVar1   // 16#0000FFFF : (65535)
[COLOR="#FF0000"]L   -1        // 16#0000FFFF : wird als 16-Bit-Wert geladen! AKKU1-H wird auf 0 gesetzt - ohje![/COLOR]
+D            // 16#0001FFFE : 32 Bit Addition - addiert nicht -1 sondern +65535 !!!
T   #diVar2   // -> [COLOR="#FF0000"]131070[/COLOR]

L   #diVar1   // 16#0000FFFF : (65535)
L   L#-1      // 16#FFFFFFFF : wird als 32-Bit-Wert geladen :-) 
+D            // 16#0000FFFE : 32 Bit Addition - addiert -1
T   #diVar2   // -> 65534

weitere Fehlermöglichkeiten bei +I anstatt +D !
...

Harald
 
Wenn man sich mit den AWL-Befehlen nicht 100% auskennt dann schreibe lieber ausführlicher so wie AWL-Code aus FUP/KOP aussieht.
Fallstricke bei simpler Addition in AWL:
Code:
L   #diVar1   // 16#0000FFFF : (65535)
[COLOR=#FF0000]L   -1        // 16#0000FFFF : wird als 16-Bit-Wert geladen! AKKU1-H wird auf 0 gesetzt - ohje![/COLOR]
+D            // 16#0001FFFE : 32 Bit Addition - addiert nicht -1 sondern +65535 !!!
T   #diVar2   // -> [COLOR=#FF0000]131070[/COLOR]

Ach deshalb hab ich da gestern einen komischen Wert erhalten und als ich statt
Code:
L -1
+D
einfach
Code:
L 1
-D
gemacht habe hats funktioniert. Hatte auch nicht die Zeit da länge drüber nachzudenken, in 99% der Fälle funktionierts ja...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Dank der Zweierkomplement-Codierung von DINT kann man "relativ" (auf dem Zahlenstrahl bzw. Zahlenkreis) rechnen: beide "UDINT"-Operanden durch Subtraktion von 16#8000'0000 in den DINT-Bereich verschieben, dann DINT-Vergleich anwenden. Subtraktion von 16#8000'0000 entspricht Invertieren des höchsten Bit .31, was man als Verschiebung/Vertauschung der Werte in den jeweils anderen Bereich (16#8000'0000 .. 16#FFFF'FFFF) und (0 .. 16#7FFF'FFFF) interpretieren kann.
Habe mal versucht, mich selbst davon zu überzeugen, dass das bedingungslose Umknippsen der Bit31 beider Zahlen zum Ziel führt.
Hier das Ergebnis, das vielleicht auch anderen das Verständnis erleichtert:

Die DINT-Vergleichs-Operatoren liefern "sowieso" korrekte Ergebnisse bezogen auf die Interpretation als UDINT, ...
1) wenn beide verglichenen UDINT-Zahlen gleich sind,
2) wenn die Bit31 der beiden verglichenen UDINT-Zahlen gleich sind.

Aber '<' und '>' sind genau vertauscht, wenn
3) die Bit31 der beiden verglichenen UDINT-Zahlen unterschiedlich sind.

Was bewirkt nun das bedingungslose Umknippsen der Bit31 beider UDINT-Zahlen?
1) Sind die beiden UDINT-Zahlen gleich, so bleiben sie gleich.
2) Sind die Bit31 beider UDINT-Zahlen gleich, so bleibt die kleinere der beiden die kleinere und die grössere bleibt die grössere.
3) Sind die Bit31 beider UDINT-Zahlen unterschiedlich, so wird im Sinne der DINT-Interpretation aus der negativen eine positive und umgekehrt.

Zu 1)
Trivial, oder?

Zu 2)
Das ist bei Zahlen so, die im ZweierKomplement dargstellt werden.
Man nehme zwei positive, aber unterschiedliche DINT-Zahlen, z.B.
00000000 00000000 00000000 00000001 (= dez. 1)
00000000 00000000 00000000 00000010 (= dez. 2)
und manipuliere beide durch Umknippsen der höchstwertigen Bits (Bit31) in negative Zahlen
10000000 00000000 00000000 00000001 (= dez. -2.147.483.647)
10000000 00000000 00000000 00000010 (= dez. -2.147.483.646)
Die kleinere der beiden ist auch nach der Manipulation die kleinere im Sinne der DINT-Interpretation ... und wird somit "trotz" DINT-Interpretation richtig als kleinere erkannt.

Zu 3)
D.h., wegen unterschiedlicher Bit31 der beiden Zahlen ist eine der beiden im Sinne der DINT-Interpretation vor der Manipulation positiv und die andere negativ.
Nach der Manipulation ist aus der positiven eine negative geworden und umgekehrt. Egal, um welche beiden ZahlenWerte es sich im Einzelnen konkret handelt, der negative ist in jedem Fall der kleinere und der positive der grössere.
Hier wird also der einzig erforderliche Tausch für die unterschiedlichen Interpretationen von DINT und UDINT vollzogen.

Gruss, Heinileini
 
Die Zweierkomplement-Darstellung war schon eine geniale Idee :D und wenn man sich die Zahlen auf einem Zahlenkreis vorstellt, dann ist auch leicht verständlich was man tun muß um mit DINT-Vergleich UDINT-Werte zu vergleichen.

Harald
 
Die Zweierkomplement-Darstellung war schon eine geniale Idee :D und wenn man sich die Zahlen auf einem Zahlenkreis vorstellt, dann ist auch leicht verständlich was man tun muß um mit DINT-Vergleich UDINT-Werte zu vergleichen.
Genau, Harald.
Und das Geniale am Verfahren, generell beide 31-er Bits zu invertieren, ist:

die sich aufdrängende FallUnterscheidung (zu prüfen, ob sich bei beiden 31-er Bits unterscheiden oder nicht) erübrigt sich auf "wundersame" Weise, weil im Falle, dass die 31-er Bits gleich sind, durch die Manipulation kein Schaden angerichtet wird - das Verhältnis der beiden Zahlen zueinander bezüglich '>' und '<' bleibt unberührt - dank ZweierKomplement. Bezüglich '=' muss man nicht einmal die ZweierKomplement-Interpretation bemühen.
Die TauschAktion - in dem Falle, dass sie nötig wird (die 31-er Bits sind unterschiedlich) - erledigt sich elegant durch das Invertieren beider Vorzeichen, ohne dass man die restlichen Bits überhaupt näher betrachten muss.

Gruss, Heinileini
 
Zurück
Oben