Absolut Betrag "ausrechnen"

Krumnix

Level-3
Beiträge
1.454
Reaktionspunkte
190
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo.

Ich hab hier ne Steuerung (iTNC530) welche keinen ABS Befehl kennt.
Gibt es eine Möglichkeit mit einer Formel den "Abstand" zu Null, also den absolut Betrag zu errechnen?

Ich möchte keine IF Bedingung erstellen, da ich die Auswertung auch an andere Stelle brauche, wo IF nicht funktioniert.

Jemand einen Tipp?
Danke!
 
Nimm doch deinen Wert und den mit -1 multiplizierten Wert und bilde daraus eine Maxauswahl.
Das Ergebnis sollte dann dein Betragswert sein.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wie sieht es mit "Schieben" aus? Einmal nach links und einmal nach rechts?
Gaaanz schlecht, Onkel Dagobert!
Sogar, wenn man zwei Arten von RechtsSchieben zur Auswahl hat:
- mit Vorzeichen: damit machst Du u.U. aus einer positiven Zahl eine negative, nämlich, wenn das zweithöchstwertige Bit 1 ist.
- ohne Vorzeichen: damit machst Du u.U. aus einer negativen Zahl eine positive.
Aber in beiden Fällen: mit dem Betrag der so bearbeiteten Zahl hat das nix zu tun!
Das sogenannte VorzeichenBit heisst nur so, weil man an dem Bit ablesen kann, ob die Zahl positiv oder negativ ist.
Das "Umkippsen" des VorzeichenBits verändert aber in jedem Fall den Betrag der Zahl und nicht nur das Vorzeichen!

Ansatz:
Zahl*(Zahl>(-Zahl))+ Zahl*(Zahl<(-Zahl)) // funktioniert in Excel, da True 1 entspricht und False 0
Wenn allerdings True -1 entspricht, müsste man z.B.
-Zahl*(Zahl>(-Zahl)) - Zahl*(Zahl<(-Zahl))
schreiben.

Korrektur:
Sorry, es war so gut gemeint, aber trotzdem so falsch! Also, jetzt mit ohne TippFehler (hoffentlich):
Zahl*(Zahl>(-Zahl)) - Zahl*(Zahl<(-Zahl)) // funktioniert in Excel (TabellenBlatt), da True 1 entspricht und False 0
Wenn allerdings True -1 entspricht, müsste man z.B.
Zahl*(Zahl<(-Zahl)) - Zahl*(Zahl>(-Zahl)) // z.B. in VBA
schreiben!

 
Zuletzt bearbeitet:
In Step7 bedeutet "ABS": Absolutwert einer Gleitpunktzahl
Da funktioniert die Betragsbildung tatsächlich so, daß das höchste Bit .31 (das Vorzeichenbit) auf 0 gebracht wird, weil bei Gleitkommazahlen nach IEEE 754 (REAL) das Vorzeichen und der Betrag der Zahl getrennt gespeichert sind.

Bei Ganzzahlen (Festpunktzahlen) funktioniert das nicht, weil die im Zweierkomplement gespeichert sind und es kein isoliertes Vorzeichenbit gibt.

Das höchste Bit auf 0 setzen kann man durch maskieren/ausblenden: "AbsBetrag := realValue AND DW#16#7FFFFFFF"
oder auch durch das vom Onkel erwähnte 1 Bit Links- und nachfolgend 1 Bit Rechtsschieben. Wichtig: das Rechtsschieben muß ein 0-Bit einschieben.

Die Max-Funktion halte ich für am besten, weil die mit Gleitpunktzahlen und auch mit Ganzzahlen gleich funktionieren würde. (SCL, ST, FUP, KOP, CFC) Welche Anweisungen die hier verwendete NC-Steuerung kann, weiß ich aber nicht. Vermutlich läßt sich da auch eine Rechenformel ohne IF (ohne Sprünge) finden.

Harald
 
Vermutlich läßt sich da auch eine Rechenformel ohne IF (ohne Sprünge) finden.
Davon gehe ich auch aus und das hatte ich in #6 gemeint. Leider hatte ich dort + und - verwechselt :oops:
Hab dort die Korrektur angefügt.
Die beiden dortigen Formeln habe ich nun zu einer zusammengefasst, durch Hinzufügen von "* (0=0)", wodurch nun egal ist, ob TRUE ProgrammierSprachen-abhängig den ZahlenWert 1 oder -1 hat:

AbsVonZahl = (Zahl * (Zahl > (-Zahl)) - Zahl * (Zahl < (-Zahl)) * (0 = 0)

Natürlich geht das auch noch etwas kompakter, da ABS(Zahl) = SGN(Zahl) * Zahl ist:
Mit
SgnVonZahl = ((Zahl > 0) - (Zahl < 0)) * (0 = 0)
erhält man
AbsVonZahl = ((Zahl > 0) - (Zahl < 0)) * (0 = 0) * Zahl

Vorausgesetzt wird aber weiterhin, dass die ProgrammierSprache mit den Bool-Ergebnissen der Vergleiche weiterrechnen kann, also automatisch die TypKonvertierung durchführt oder grosszügig über den TypenMischMasch hinwegsieht. Falls nicht, müsste man die 3 TypKonvertierungen noch ergänzen - sofern sie in der ProgrammierSprache nicht auch noch wegrationalisiert wurden.

Apropos Typ: Zahl kann eine Ganzzahl oder GleitKommaZahl sein.
 
Den Algorithmus aus dem Beitrag #8 habe ich jetzt mal in AWL umgesetzt.
Ist erstaunlich kurz geworden.
Code:
FUNCTION "MyAbs2" : DINT
TITLE =Abs von DInt ohne Sprung

VAR_INPUT
  v : DINT ;    
END_VAR
BEGIN
NETWORK
TITLE =

      L     #v; 
      SSD   31; // Vorzeichen in alle Bits kopieren (mask)
      L     #v; 
      XOD   ; // XOR mit dem Eingangswert
      TAK   ; 
      -D    ; // mask subtrahieren
      T     #RET_VAL; // das war's

END_FUNCTION
In SCL wird es etwas länger weil man wegen der Typprüfung mehrmals von DINT nach DWORD und umgekehrt umwandeln muss.
Gruß
Erich
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ist erstaunlich kurz geworden.
. . .
In SCL wird es etwas länger weil man wegen der Typprüfung mehrmals von DINT nach DWORD und umgekehrt umwandeln muss.
Wen erstaunt das?

Ein "bedingter NEGD" also, aber eben ohne SprungBefehl.

Das ist ja das "perverse", dass die vermeintlichen TypKonvertierungen in diesem Fall nichts anderes tun, als "nur" die TypPrüfung zu befriedigen.
Wirkliche Konvertierungen finden nicht statt, weil sich das BitMuster nicht verändert.
Der ganze Aufwand dient lediglich dazu, zu testen, ob der Programmierer schon am einnicken ist.

PS:
Ich möchte keine IF Bedingung erstellen, da ich die Auswertung auch an andere Stelle brauche, wo IF nicht funktioniert.
Nur aus reiner Neugier: Was ist denn an anderen Stellen so anders, dass an denen IF nicht funktioniert?
 
Zuletzt bearbeitet:
... dass die vermeintlichen TypKonvertierungen in diesem Fall nichts anderes tun, als "nur" die TypPrüfung zu befriedigen.
Wirkliche Konvertierungen finden nicht statt, weil sich das BitMuster nicht verändert.
Der ganze Aufwand dient lediglich dazu, zu testen, ob der Programmierer schon am einnicken ist.
Ich mag das, wahrscheinlich deshalb, weil ich schon immer lieber Pascal/Delphi als C programmiere. Ich sehe diese Typumwandlungen die nichts umwandeln so, dass damit der Programmierer dem Compiler sagt: Schweig, ich weiß was ich tue.
Gruß
Erich
 
Mein Problem dabei ist, dass die Steuerung mit nur + - * / anbietet sowie die Standard-Funktionen A O AN ON XOR ...

Im Moment mache ich das alles über eine IF-Abfrage. Sprich, wenn der Wert <0 dann * -1.
Ein IF kann ich aber später in einem IF-Kopf nicht wieder verwenden und suche hier eine andere Lösung.

Beispiel:
Code:
L   Var1
ABS                 <--- Das ist ein "Marko"
> 20
IFT
   BlaBlaBla
ENDI

ABS-Makro:
Code:
PL
<0
IFT
  * -1
ENDI
PS

Das IFT in einen IF-Kopf geht leider nicht. Suche noch Lösungen dazu :)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Welche Datentypen kann die Steuerung? Kann sie TypeCasts oder Typ-Konvertierungen? Was passiert wenn bei einer Operation ein Datentyp-Überlauf auftritt (z.B. Int: 32000 + 10000, oder 60000 + 10000)?
Mit welchem Datentyp oder welchen Datentypen soll Dein ABS-Makro funktionieren?
Kann die Steuerung "MOD"?

(Bist Du sicher, daß die Steuerung keine ABS-Funktion hat?)

Harald
 
@PN/DP
Ja, bin mir sicher, dass sie kein ABS kann. Aussage vom Hersteller. ABS für INT/WORD/DINT/DWORD gibt es nicht.
Nur für Real/Float, eingeführt vor ein paar Jahren...

Die Steuerung, bzw. der Compiler bietet einem an, Funktionen, welche man mehrmals benötig als sogenannte Makros zu schreiben und diese können dann überall mit einem kurzen Aufruf gestartet werden.
Dabei wird jedoch nicht eine Übergabe an eine Funktion ausgeführt (z.B. bei C++ oder ein FB/FC bei Siemens, welcher dann abgearbeitet wird), sondern der in dem Makro geschrieben Code einfach nur eingefügt wird.

Wenn ich z.B. eine Berechnung mehrmals machen möchte, die Formel dazu aber immer gleich ist, erstelle ich ein Makro und nutze dies dann immer.

Beispiel:
Formel: r = a + b + c + d

Makro:
Code:
#define /m Formal1(value_a,value_b,value_c,value_d,result_r)
  L (value_a)
  + (value_b)
  + (value_c)
  + (value_d)
  = (result_r)

Wenn ich das nun im Programm einfüge wäre das z.B. so:
Code:
Formel1(10,20,30,40,M_Ergebnis)
L M_Ergebnis
.....

Der Compiler macht danach in der fertig zu übertragenen Datei folgendes:
Code:
  L 10
  + 20
  + 30
  + 40
  = M_Ergebnis
L M_Ergebnis
.....

Wenn ich das nun mit einem Vergleich mache, ob eine Zahl kleiner Null ist und ich sie dann Multipliziere mit -1, dann habe ich ein IF in einem IF-Kopf:
Code:
L  AABBCC
A  BBCCDD
> ABS(TestZahlABS)
  L TestZahlABS
  < 0
  IFT
    L  TestZahlABS
    X  K-1
    =  TestZahlABS
  ENDI
IFT
  BlaBlaBla
ENDI

Das funktioniert aber nicht...

Daher bin ich auf der Suche nach einer Lösung, welche nur mit + - * / zum Ergebnis kommt....
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@Heinileini:
Sonst würde ich nicht weiterhin hier fragen...
Deine Vorschläge funktionieren auf der iTNC530 nicht, da diese einen Vergleich in einer Formel ohne Einsatz von IFT nicht auswertet.
 
@Krumnix
Ich bin leider etwas schwer von Begriff und habe immer noch nicht verstanden, was mit "IF im IF-Kopf" gemeint ist.
Bedeutet das, dass IF-Abfragen nicht verschachtelt werden können?
Kann man denn IF-Abfragen in Makros nicht verwenden?
Gibt es (wider Erwarten) eine SIGN-Funktion?
Was ist das überhaupt für eine Sprache? Erinnert mich an (optisch aufgepeppte) AWL.
Ich hatte zum Thema iTNC530 einiges bei Heidenhain gefunden, aber bisher noch nichts, was Deinen Beispielen ähnelt.
Gibt's da was "für zum" Runterladen als pdf?

@Michael
Nach Weihnachten ist vor Weihnachten, also könnten wir dieses Thema vormerken.
 
Zurück
Oben