Gleitzahl in Mantisse und Exponent zerlegen

emtewe

Well-known member
Beiträge
105
Punkte Reaktionen
0
Zuviel Werbung?
->Hier kostenlos registrieren
Hallo,

ich habe eine Simatic S7-300 315-2 DP, und als Software die Simatic Step 7 V 5.2

Von einem Profibusteilnehmer bekomme ich einen Messwert als Gleitzahl im Bereich zwischen 1000 und 0,5 E -10
Das Display in welchem der Wert angezeigt werden soll kann nur Integerzahlen darstellen.

Jetzt suche ich einen eleganten Weg um die Gleitpunktzahl 32 Bit in eine 4stellige Mantisse und einen 2stelligen Exponenten mit Vorzeichen zu zerlegen.

Im Moment würde ich die Zahl wiederholt mit 10 multiplizieren, oder durch 10 dividieren, bis das Ergebnis größer, bzw. kleiner 1 ist, um so den Exponent zu ermitteln. Danach würde ich die Mantisse durch Division bzw. Multiplikation mit der ursprünglichen Zahl mit dem Exponenten bestimmen, auf 4 Stellen kürzen usw...
Das erscheint mir aber als keine sehr elegante Lösung, hat vielleicht jemand eine bessere Idee?

mfG
emtewe
 

Zottel

Well-known member
Beiträge
2.299
Punkte Reaktionen
277
emtewe schrieb:
Hallo,

ich habe eine Simatic S7-300 315-2 DP, und als Software die Simatic Step 7 V 5.2

Von einem Profibusteilnehmer bekomme ich einen Messwert als Gleitzahl im Bereich zwischen 1000 und 0,5 E -10
Das Display in welchem der Wert angezeigt werden soll kann nur Integerzahlen darstellen.
Was soll es denn darstellen bei z.B. 0,456 ?
0, dann reicht runden.

Oder willst du Mantisse und Exponent anzeigen? Das nehme ich mal an.

Den Exponenten kannst du über Logarithmen bestimmen: Bei einer Zahl zwischen 1000 und 9999.9... hat der Logarithmus zur Basis 10 die 1. Stelle 3. Der ganzzahlige Anteil des Logarithmus ist dein Exponent. Wenn du ihn vom Logarithmus abziehst und 10 hoch (Nachkommastellen des Logarithmus) rechnest, bekommst du die Mantisse.

Weiß jetzt nicht, ob die S7 die Funktion "Logarithmus zur Basis 10" (dekadischer Logarithmus) hat.
Wenn nicht: Logarithmus zur Basis 10(x) = natürlicher Logarithmus(x)/ natürlicher Logarithmus(10) .
 

Peter Wahlen

Well-known member
Beiträge
389
Punkte Reaktionen
130
Zuviel Werbung?
->Hier kostenlos registrieren
Hallo emtewe,

Du kannst die Mantisse und den Exponenten auch durch ausmaskieren aus der Gleitpunktzahl holen. Das Format von Gleitpunktzahlen ist sehr gut in der Hilfe zu S7 (Zahlendarstellung, Gleitpunkt) beschrieben.

vill jröß (viele Grüße)

Peter
 

Ralle

Supermoderator
Teammitglied
Beiträge
14.403
Punkte Reaktionen
3.373
Hallo emtewe

Hier mal eine Delphi-Funktion, da kannst du rausnehmen was du benötigst.

Code:
//Übergabe einer Gleitpunktzahl von S7 an Delphi
//eingelesen werden 4 Byte, diese werden zu einer Integer-Zahl aufaddiert (-->Daten)
//und müssen dann in eine Delphi-Gleitpunktzahl umgewandelt werden
function S7_Float(Daten: Integer): Real;
var
  Exp, Mant, Count: Integer;
  Mant_r, D_Real: Real;
begin
  Exp := ((Daten shl 1) shr 24) - 127;
  Mant := (Daten shl 9) shr 9;

  Mant_r := 0;
  Count := 1;
  while Count <= 23 do
  begin
    //nachsehen, ob Bit an Stelle Count 0 oder 1
    if ((Mant and (1 shl (23 - Count))) > 0) then
      Mant_r := Mant_r + Power(2 , -Count);
    Count := Count + 1;
  end;
  //eine echte Null erzeugen !!!
  if ((Exp = -127) and (Mant = 0)) then
    Mant_r := 0
  else
    Mant_r := 1 + Mant_r;
  D_Real := Mant_r * Power(2, Exp);
  //Vorzeichen testen und einrechnen
  if ((Daten shr 31) > 0) then
    S7_Float := -D_Real
  else
    S7_Float := D_Real;
end;

Ist vieleicht etwas umständlich, funktioniert aber :lol:
 
OP
E

emtewe

Well-known member
Beiträge
105
Punkte Reaktionen
0
Danke an alle, ich werde erstmal die Maskierungsmethode probieren, das scheint mir für die Zykluszeiten die beste Lösung.

viele Grüße, besonders um die Ecke nach Niederkassel aus Troisdorf
Michael
 

Zottel

Well-known member
Beiträge
2.299
Punkte Reaktionen
277
Zuviel Werbung?
->Hier kostenlos registrieren
Peter Wahlen schrieb:
Hallo emtewe,

Du kannst die Mantisse und den Exponenten auch durch ausmaskieren aus der Gleitpunktzahl holen. Das Format von Gleitpunktzahlen ist sehr gut in der Hilfe zu S7 (Zahlendarstellung, Gleitpunkt) beschrieben.
Na ja, aber die interne Darstellung nach IEE754 verwendet Exponenten zur Basis zwei, nicht 10. So etwas anzuzeigen ist nicht besonders sinnvoll. Den Zehner- aus dem Zweierexponenten zu bestimmen ist natürlich möglich, wegen des gebrochenen Umrechnungsfaktors können aber nicht normierte Ergebnisse (z.B. 10.0002 E3 statt 1.00002 E4 oder 0.0999E2 statt 0.999E1 auftreten).
 
A

Anonymous

Guest
Zottel schrieb:
Na ja, aber die interne Darstellung nach IEE754 verwendet Exponenten zur Basis zwei, nicht 10. So etwas anzuzeigen ist nicht besonders sinnvoll. Den Zehner- aus dem Zweierexponenten zu bestimmen ist natürlich möglich, wegen des gebrochenen Umrechnungsfaktors können aber nicht normierte Ergebnisse (z.B. 10.0002 E3 statt 1.00002 E4 oder 0.0999E2 statt 0.999E1 auftreten).
Stimmt. Werde wohl doch auf die Variante mit Logarithmenberechnung zurückgreifen. Ich werde den LN 10 als Variable speichern um mir jedesmal die Berechnung zu ersparen.

danke nochmal an alle
Gruß
Michael
 
A

Anonymous

Guest
Hallo Emtewe,

falls dein Display Strings anzeigen kann, kannst du mit dem
FC 30 (R_STRNG) aus der IEC Bibliothek deinen Real wert in einen String verwandeln

Die Funktion FC 30 wandelt eine Variable im REAL ­Format in eine Zeichenkette. Die Zeichenkette wird mit 14 Stellen darstellt:

±v.nnnnnnnE±xx
±Vorzeichenv
1 Vorkommastellen
7 Nachkommastellenx
2 Exponentenstellen

Da du ja nur ein 4-stellige Mantisse haben willst, kannst du die überflüssigen Zeichen mit dem FC 4 (DELETE) aus der IEC Bibliothek löschen.

mfg
marlob
 
OP
E

emtewe

Well-known member
Beiträge
105
Punkte Reaktionen
0
Zuviel Werbung?
->Hier kostenlos registrieren
Gast schrieb:
Hallo Emtewe,
falls dein Display Strings anzeigen kann, kannst du mit dem
FC 30 (R_STRNG) aus der IEC Bibliothek deinen Real wert in einen String verwandeln
Gute Idee, danke. Das Display (Ebelt BT 1000) kann Zeichenketten darstellen, aber die Daten die zum Display geschickt werden landen auch in einem Datenlogger der daraus ein ASCII File erstellt welches anschliessend mit Excel ausgewertet wird. Eine Zeichenkette würde dort als 14 ASCII Zahlen ankommen. Das könnte zwar umgewandelt werden, mir wäre es aber lieber dort nur Zahlenformate abzulegen.
Gruß
emtewe
 

Jochen Kühner

Well-known member
Beiträge
4.154
Punkte Reaktionen
474
du kannst doch den exponent und die mantisse direkt aus der gleitpunktzahl auslesen...

L ED 1 //Dein Eingangswort
L DW#16#7F800000 //maskieren des exponenten
SRD 23
T EXPONENT

deann müsstes du den exponenten im akku haben.

L ED 1
L DW#16#7FFFFF
T MANTISSE

nun kannst du ja mantisse und exponenten entsprechend deinen wünschen weiterverarbeiten..
 
OP
E

emtewe

Well-known member
Beiträge
105
Punkte Reaktionen
0
Jochen Kühner schrieb:
du kannst doch den exponent und die mantisse direkt aus der gleitpunktzahl auslesen...
nun kannst du ja mantisse und exponenten entsprechend deinen wünschen weiterverarbeiten..
Die zweiten L sollten wohl jeweils ein U sein?
Ja. Dies entspricht dem Vorschlag von Zottel, weiter oben. Da ist dann aber wieder das Problem der Umrechnung des Binärexponenten in den Dezimalexponenten. Ich habe jetzt eine Lösung mit dem FC 30 (R_STRNG) für das Display, und eine Berechnung von Mantisse und Exponent für den Datenlogger. Ob das alles so funktioniert erfahre ich aber erst wenn ich den Bus hochfahre nächste Woche.
Trotzdem Danke!
Gruß
Michael
 

Zottel

Well-known member
Beiträge
2.299
Punkte Reaktionen
277
Zuviel Werbung?
->Hier kostenlos registrieren
emtewe schrieb:
... Ob das alles so funktioniert erfahre ich aber erst wenn ich den Bus hochfahre nächste Woche.
Ich weiß nicht ob dir das klar ist, aber die S7 verwendet intern dasselbe Gleitpunkt-Format. Du kannst also alles "trocken" testen.
Die Befehle:
L 456.789
T MD4
schreiben dir die Zahl in Gleitpunktdarstellung ins MD4 und du kannst mit diesem MD statt mit dem Wert vom Bus arbeiten. Die Darstellung als String kannst du dir auch mit "Variable beobachten" ansehen, z.B.0.456789 E3.
 
Oben