DWORD_TO_REAL( REAL_TO_DWORD( REAL ) ) unterschiedlich?!

Zuviel Werbung?
-> Hier kostenlos registrieren
Ah, da ist jemand mit einer Goldwaage unterwegs?! Dem Mann kann geholfen werden. :ROFLMAO:

Klingt unglaublich. Hättest Du mal ein Beispiel wer sich nicht an die IEEE hält? ;)
Wie in dem weiter oben von mir verlinkten Artikel bei Wikipedia zu lesen ist, halten sich z.B. einige Systeme von IBM nicht daran, welche, nebenbei bemerkt, ab 2000 am Markt sind. Ich sagte nicht, was wohl aus meiner Aussage herausgelesen werden konnte, daß Beckhoff und/oder KUKA sich nicht daran halten. Diese missverständliche Formulierung bitte ich zu entschuldigen.

Es wäre noch anzufügen, daß sich bei meiner weiteren Recherche herausgestellt hat, daß, obwohl es im zuvor geposteten Ausschnitt den KUKA-Handbuches nicht explizit erwähnt wird, KUKA sich scheinbar auch daran hält. Zumindest stimmen die im Handbuch angegebenen Grenzen mit denen in der IEEE angegebenen Werten (1) exakt überein: 1.1E-38 bis 3.4E38.


Da kommt ziemlich sicher nicht ein "verdammt großes INT" an, sondern 32 Bits in 4 Bytes, die sich irgendjemand fälschlicherweise als Ganzzahl anschaut. Dabei muß man sich das Bitmuster der 4 Bytes einfach nur als REAL anschauen, dann sieht man, daß das tatsächlich ein REAL ist.
Auch hier entschuldige ich meine unklare Ausdrucksweise. Genauer gesagt passiert folgendes:
Ich setze in der SPS eine REAL-Variable, die zusammen mit einem DWORD in der oben geposteten UNION steht, auf den Wert 18.4. In dem DWORD steht dann das korrekte Bituster dieses Wertes drin: 01000001100100110011001100110011.

Das DWORD aus der UNION wird dann via Schnittstelle an den KUKA geschickt. Beim Roboter kommt es auf einem Gruppensignal (SIGNAL GI_Signalname $in[...] TO $in[...] ) an. Im Gruppensignal ist das Bitmuster korrekt, d.h. die einzelnen binären Eingänge sind korrekt gesetzt: 01000001100100110011001100110011. Als INT interpretiert entspricht das dem Wert 1100165939. Wenn ich jetzt der REAL-Variable (REAL R_realname ) diesen Wert zuweise, dann steht nicht 18.4 in der REAL, wie man es erwarten würde, sondern "ein verdammt großer INT", genauer gesagt die INT-Repräsentation des Gruppensignales, der oben genannte Wert von 1100165939, in REAL-Darstellung, d.h. 1.1006589E+09.

An diesem Punkt wäre das Thema für mich - eigentlich - beendet, da ich aber auch KUKA programmiere und ich auch schon ab und an über dieses Problem gestolpert bin, war es mir ein Anliegen es auch zu lösen. Völlig ohne Eigennutz natürlich. :ROFLMAO:

Das Problem konnte inzwischen auch dank der tatkräftigen Hilfe eines KUKA-Technikers gelöst werden. Um wieder die 18.4 in die REAL-Variablen zu bekommen, wird der Gruppeneingang als stream betrachtet und in einer kleinen Funktion (ein 5-Zeiler) mittels cast_from auf eine temporäre Variable geschrieben, welche wiederum mit cast_to, beide Bestandteil von CREAD/CWRITE, in die real-Variable geschrieben wird. Im Programm sieht das dann so aus:

Code:
; So geht es nicht:
R_realname = GI_Signalname

; Aber so geht es. stream2real ist eine kleine Hilfsfunktion:
R_realname = stream2real(GI_Signalname)


Ich will Dir nicht zu nahe treten, aber sorry: Was hast Du eigentlich für einen Job, daß Du für die Lösung simpler Standard-Probleme mehrere Tage verdaddeln kannst? Vielleicht sollte Dein AG Dich mal zu einem guten Programmier-Lehrgang schicken? :cool: Wenn andere Leute etwas für Dich unverständliches tun, dann heißt das nicht automatisch, daß "die Anderen" etwas falsch machen...
Du trittst mir nicht zu nahe. Besonders nicht, wenn Du die Aussage "Du bist imkompetent" durch einen so großen und hübschen Strauß Blumen sagst. :p
Es wurde sich hier im Forum auch schon bei mir entschuldigt. :eek:

Scheinbar wird die Netiquette hier gepflegt. Zusammen mit der i.d.R. sehr schnellen und kompetenten Hilfe, die man hier bekommt, auch, wenn man mal "noob"-Fragen stellt, macht das dieses Forum äußerst sympatisch. Einzig der facepalm-Smiley fehlt mir zur vollkommenen Glücksehligkeit. :ROFLMAO:

Ein "bißchen was" verstehe ich vom programmieren übrigens schon, bei TwinCAT 3 bin ich aber tatsächlich "noob".

Ich hoffe ich konnte alle Klarheiten beseitigen und gelobe zukünftig größere Sorgfalt bei meinen Fragestellungen und meinen Antworten walten zu lassen. :)

Gruß
Jörn

(1) https://de.wikipedia.org/wiki/IEEE_754
 
Zuletzt bearbeitet:
Wenn ich jetzt der REAL-Variable (REAL R_realname ) diesen Wert zuweise, dann steht nicht 18.4 in der REAL, wie man es erwarten würde, sondern "ein verdammt großer INT", genauer gesagt die INT-Repräsentation des Gruppensignales, der oben genannte Wert von 1100165939, in REAL-Darstellung, d.h. 1.1006589E+09.
Vermutlich das gleiche Problem wie bei allen Codesys-Dialekten: der Compiler macht da keine Zuweisung des Bitmusters sondern konvertiert den Wert von Ganzzahl zu REAL. Man bräuchte einen type cast, den es aber in Codesys nicht gibt. Da läßt sich der Datentyp eines Bitmusters nur ändern durch Umkopieren mittels Pointer oder MEMCOPY oder UNION.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Jetzt will ich vom Jörn aber immer noch wissen, wie die Schnittstelle zu seinem Roboter aufgebaut ist. Welches Format die Fließkommazahlen haben ist ja zweitrangig. Es muss doch eine Art Tabelle geben in der steht, was in welcher Reihenfolge übertragen wird.

Erst dann können wir die richtihe Lösung finden
 
@ ms_gp:
Um Deine Frage aus Post #13 zu beantworten wie das zustande kommt:
Der Roboterprogrammierer hat ohne Absprache, wie es eigentlich ausgemacht war, die Schnittstelle einfach mal auf Roboterseite definiert. Ich musste die dann so übernehmen. Und jetzt möchte er es nicht mehr ändern, weil es so viel Aufwand ist.


Mit Augenmerkt auf die dword sieht die Schnittstelle so aus:

Code:
dword[0]  - 32 BOOL
dword[1]  - 32 BOOL
dword[2]  - 16 BOOL,   INT
dword[3]  - INT,       INT
dword[4]  - INT,       hi REAL1
dword[5]  - lo REAL1,  hi REAL2
dword[6]  - lo REAL2,  hi REAL3
dword[7]  - lo REAL3,  hi REAL4
// weitere REAL
dword[12] - lo REAL8,  hi REAL9
dword[13] - lo REAL9,  hi REAL10
dword[14] - lo REAL10, INT
dword[15] - INT,       INT
dword[16] - INT,       INT
dword[17] - INT,       INT
dword[18] - INT,       hi REAL11
dword[19] - lo REAL11, hi REAL12
dword[20] - lo REAL12, hi REAL13
dword[21] - lo REAL13, INT
dword[22] - INT,       hi REAL14
dword[23] - lo REAL14, hi REAL15
dword[21] - lo REAL13, INT
dword[22] - INT, hi REAL14
dword[23] - lo REAL14, hi REAL15
// weitere REAL
dword[30] - lo REAL21, hi REAL22
dword[31] - lo REAL22, INT


Mit Augenmerk auf die eigentlichen Signale sieht sie so aus:

Code:
// Ausschnitt

...
dword[4].0-15                    - INT
dword[4].16-31  + dword[5].0-15  - REAL1
dword[5].16-31  + dword[6].0-15  - REAL2
...
dword[13].16-31 + dword[14].0-15 - REAL10
dword[14].16-31                  - INT
...


Das Mapping hab ich dann so gelöst. Ich hab in die union noch zwei word mit reingenommen, wie Harald es vorschlug:

Code:
// Ausschnitt

...
IOstRob.uRobIn.arDwordRobIn[2].13 := stKukaInOEM.bx9_5;
IOstRob.uRobIn.arDwordRobIn[2].14 := stKukaInOEM.bx9_6;
IOstRob.uRobIn.arDwordRobIn[2].15 := stKukaInOEM.bx9_7;
IOstRob.uRobIn.arDwordRobIn[2]    := SHL(INT_TO_DWORD(stKukaInOEM.ix10), 16) OR IOstRob.uRobIn.arDwordRobIn[2];
IOstRob.uRobIn.arDwordRobIn[3]    := SHL(INT_TO_DWORD(stKukaInOEM.ix14), 16) OR INT_TO_DWORD(stKukaInOEM.ix12);


ioPuffer[1].uReal  := stKukaInOEM.rx18Entn1Versatz;
ioPuffer[2].uReal  := stKukaInOEM.rx24Entn1_X;
ioPuffer[3].uReal  := stKukaInOEM.rx28Entn1_Y;
...


IOstRob.uRobIn.arDwordRobIn[4]    := ioPuffer[1].uWord[loWord] OR INT_TO_DWORD(stKukaInOEM.ix16);
IOstRob.uRobIn.arDwordRobIn[5]    := ioPuffer[2].uWord[loWord] OR ioPuffer[1].uWord[hiWord];
IOstRob.uRobIn.arDwordRobIn[6]    := ioPuffer[3].uWord[loWord] OR ioPuffer[2].uWord[hiWord];
...
 
Zuletzt bearbeitet:
Du könntest vor dem Mapping (Umkopieren der einzelnen Werte) das empfangene DWORD-Array auf eine zur tatsächlichen Struktur passende Struktur kopieren (z.B. MEMCPY), das würde das Mapping erheblich vereinfachen.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Der Roboterprogrammierer hat ohne Absprache, wie es eigentlich ausgemacht war, die Schnittstelle einfach mal auf Roboterseite definiert. Ich musste die dann so übernehmen.
Das ist doch nicht unnormal, das passiert jedem von uns. Wenn das Fremdsystem z.B. eine Wiegeeinrichtung wäre, dann fragt der Waagehersteller Dich auch nicht, wie Dir die Schnittstelle angenehm wäre, sondern er implementiert eine Standard-Schnittstelle nach seinen Vorstellungen.

Es ist doch eigentlich Wurst wie der Roboterprogrammierer die Schnittstelle definiert hat, Hauptsache man kann sie im eigenen System nachbauen (in STEP7 kann man z.B. keine INT/REAL/... auf einer ungeraden Adresse anfangen lassen). Dafür erstellt man sich eine Struktur die die logische Struktur der Schnittstelle abbildet und kopiert die Empfangsdaten aus dem Empfangspuffer (z.B. Byte/Word/DWord-Array) "am Stück" (MEMCPY) in diese Struktur und kann sich dann die einzelnen Variablen easy auf eine weitere Arbeits/Koppelstruktur umkopieren, deren Variablen dann im Programm verwendet werden.

z.B.
Code:
//pragma pack... ?

STRUCT
  Bit_1_1 : BOOL;
...
  Bit_1_32 : BOOL;
  Bit_2_1 : BOOL;
...
  Bit_2_32 : BOOL;
  Bit_3_1 : BOOL;
...
  Bit_3_16 : BOOL;
  Int_1 : INT;
  Int_2 : INT;
  Int_3 : INT;
  Int_4 : INT;
  Real_1 : REAL;
  Real_2 : REAL;
...
END_STRUCT
(bei Codesys/Twincat weiß ich nicht wie man ein BOOL auf ein Bit deklariert - evtl. mit einem Pragma?)

Ich arbeite nur mit solchen Datenstrukturen für Empfangs/Sende-Daten, weil bei Kommunikation mit Fremdsystemen eigentlich fast immer Byte/Word/DWord-Arrays übertragen werden, die nicht der wirklichen logischen Struktur entsprechen.

Harald
 
Ganz so einfach ist es wohl nicht. Wenn ich es richtig sehe, müssen low und high word der REALs auch noch getauscht werden. Trotzdem wäre eine Lösung mit einer UNION elegant. Vielleicht so:
Erstmal ein paar Typen:
Code:
TYPE arrHW :   // Für Verknüpfung mit der HW
   ARRAY[0..31] OF DWORD;
END_TYPE

TYPE str32Bits :   // Bit-Struktur mit 32 Bits (einzelne Bits gibt es bei Codesys nicht)
STRUCT
   Bit00,
   Bit01,
   // Bit02..Bit30
   Bit31:BIT;
END_STRUCT
END_TYPE

TYPE str16Bits :   // Bit-Struktur mit 16 Bits
STRUCT
   Bit00,
   Bit01,
   // Bit02..Bit14
   Bit15:BIT;
END_STRUCT
END_TYPE

{attribute 'pack_mode' := 1} 
TYPE strPLC :   // Struktur für das PLC-Programm
STRUCT
   Bits_0_31:str32Bits;   // 0
   Bits_32_63:str32Bits;   // 4
   Bits_64_79:str16Bits;   // 8
   Int1,   // 10
   Int2,   // 12
   Int3,   // 14
   Int4:INT;   // 16
   Real1,   // 18
   Real2,   // 22
   Real3,   // 26
   Real4,   // 30
   Real5,   // 34
   Real6,   // 38
   Real7,   // 42
   Real8,   // 46
   Real9,   // 50
   Real10:REAL;   // 54
   Int5,   // 58
   Int6,   // 60
   Int7,   // 62
   Int8,   // 64
   Int9,   // 66
   Int10,   // 68
   Int11,   // 70
   Int12:INT;   // 72
   Real11,   // 74
   Real12,   // 78
   Real13:REAL;   // 82
   Int13,   // 86
   Int14:INT;   // 88
   Real14,   // 90
   Real15:REAL;   // 94
   Int15,   // 98
   Int16:INT;   // 100
   Real16,   // 102
   Real17,   // 106
   Real18,   // 110
   Real19,   // 114
   Real20,   // 118
   Real21:REAL;   // 122   Real22 wäre eins zuviel, verzählt?
   Int17:INT;   // 126
END_STRUCT
END_TYPE

{attribute 'pack_mode' := 1} 
TYPE strSwap : Für Lo/hi word-Tausch in REALS
STRUCT
   W1:WORD;   // Word dummy 1
   DW:ARRAY[0..30] OF DWORD;   // DWORDs auf den späteren REAL-Adressen
   W2:WORD;   // Word dummy 2
END_STRUCT
END_TYPE

TYPE uniKukaInterface :
UNION
   HW:arrHW;
   PLC:strPLC;
   Swap:strSwap;
END_UNION
END_TYPE
Und dann noch ein bisschen Code:
Code:
FOR Loop:=4 TO 13 DO   // Real 1..10
   KukaInterface.Swap.DW[Loop]:=ROL(KukaInterFace.Swap.DW[Loop],16);
END_FOR
FOR Loop:=18 TO 20 DO   // Real 11..13
   KukaInterface.Swap.DW[Loop]:=ROL(KukaInterFace.Swap.DW[Loop],16);
END_FOR
FOR Loop:=22 TO 23 DO   // Real 14,15
   KukaInterface.Swap.DW[Loop]:=ROL(KukaInterFace.Swap.DW[Loop],16);
END_FOR
FOR Loop:=25 TO 30 DO   // Real 16..21
   KukaInterface.Swap.DW[Loop]:=ROL(KukaInterFace.Swap.DW[Loop],16);
END_FOR
 
Zuletzt bearbeitet:
@StructuredTrash
Sehe ich das richtig, daß Du Werte liest, swapst, und auf sich selbst zurückspeicherst? Das würde ich nicht machen, weil das darf man nur dann genau einmal machen wenn man neue Daten erhalten hat. Ich würde immer umkopieren auf einen zweiten Arbeits-Speicherbereich - mit oder ohne Swap, je nach dem wie es nötig ist. Dann ist auch egal in welcher Task ich mit den Daten im Arbeits-Speicherbereich arbeite.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@PN/DP:
Dein Einwand ist natürlich berechtigt. Der Swap-Code-Aufruf und die weitere Bearbeitung der Daten müssen in der Task erfolgen, an der die EtherCat-Bridge hängt, und der Datenaustausch zwischen den beiden EtherCat-Strängen muss synchron laufen. Mit der EL6695 soll das laut Beckhoff möglich sein. Ich habe aber selbst mit dieser Bridge noch nicht gearbeitet.
Aber auch wenn umkopiert werden muss, ist so eine Union hilfreich. Wenn man beide Variablen vom Uniontyp hat, kann man das mit einer einfachen Zuweisung machen.
 
Zuletzt bearbeitet:
Ich frage mich wirklich, was sich der Roboter-Programmier dabei gedacht hat. Der hätte doch nur das letzte INT nach oben schieben müssen und alles wäre gut gewesen. Aber man kann sich auch schwer machen. Aber ich hab's ja schon gesagt. Mit Schnittstellen kann man ganz Völkerscharen beschäftigen. Und am Ende braucht man eh immer nur 3 der Werte und 3 Bits und der Rest ist für den Eimer. ;)

Na ja. Ich weiß nicht, ob es in diesem Fall geht, aber wir tauschen auch Daten zwischen unseren Steuerungen mit der EL6695 aus. Dabei definieren wir aber gar kein Array of Irgendwas, sondern schreiben einfach genau ein PDO vom Type der Schnittstelle in die Klemme. Dann verknüpft man dieses PDO mit der Variable im Programm. Wenn auf beiden Steuerungen die Struktur gleich definiert wurde, dann funktioniert das. Ohne Zwischenschritt. Ist eigentlich genauso als würde man Variablen zwischen Tasks austauschen. Allerdings gibt's da keine Probleme mit den Indianern und das Byte Alignment ist bekannt und kann gleich eingestellt werden.
 
Ich frage mich wirklich, was sich der Roboter-Programmier dabei gedacht hat.
Vielleicht hat er einfach mit MEMCPY seine Struktur in das DWord-Array der Klemme kopiert, oder arbeitet mit einer UNION seiner Struktur und einer DWord-Struktur für die Klemme (Hauptsache die Gesamtlänge stimmt und Konsistenz ist über die gesamte Länge, und eine DWord-Struktur macht am wenigsten Schreibarbeit) und gedacht, der Partner könne das genau so einfach machen?
Oder ist da noch irgendwo ein Word-Array beteiligt (wie bei Modbus)? Da wäre es aus seiner Sicht egal in welche Nachbar-Words die Reals aufgeteilt werden.

Was mich ein bisschen wundert ist, daß bei den Reals nur die H/L-Words vertauscht sind und nicht alle 4 Bytes, wie bei einem big-endian/little-endian-Problem zu erwarten wäre (die Byte-Reihenfolge ist 3412 anstatt 4321) - Warum?

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Was mich ein bisschen wundert ist, daß bei den Reals nur die H/L-Words vertauscht sind und nicht alle 4 Bytes, wie bei einem big-endian/little-endian-Problem zu erwarten wäre (die Byte-Reihenfolge ist 3412 anstatt 4321) - Warum?

1) "Hey, ich hab' ne Intel-CPU. Du musst noch die Bytes tauschen!"
2) "Warum soll ich die ganze Arbeit allein machen. Ich tausche die Bytes, um die Words soll sich der andere kümmern."
3) Es ist was ganz Spezielles, und die Behauptung, eine nachträgliche Änderung wäre zu aufwändig, ist mehr als nur eine Ausrede.
 
Hallo Ihr Lieben,

ich habe mich auch an die Umwandlung FloatToReal versucht. Leider komme ich nicht so recht auf einen Nenner. Sobald meine Floatzahl kleiner 1 wird erhalte ich kein ergebnis mehr. Ich habe mich jetzt 2 Tage damit beschäftigt aber mein Verstand reicht scheinbar nicht dafür aus. :icon_cry:
Grundlage war Wikipedia: https://de.wikipedia.org/wiki/IEEE_754

Zuerst ordne ich die Bytes in ein DWord. Danach nehme ich das DWord und zerlege es in Vorzeichen,Mantisse und Exponent und verrechne dies.
Dies funktioniert aber leider nich unter 1(als Realwert).
Das Ergebniss wird als Infinity wiedergegeben obwohl wenn ich dies selbst nachrechne das gerechnete ergebnis richtig scheint.

Zahl: 0,627009646302255
DWORD: 1059095476

rErgebnis := rVZ*rManti*(EXPT(2, usiExponent-127)); = 1(VZ)* 1,25(Manti) * 0,5(Exponent) = 0,625(Infinity)

DWordToReal.PNG Berechnung.jpg

Vielleicht kann mir jemand helfen mein Problem zu finden.
 
ich habe mich auch an die Umwandlung FloatToReal versucht.
Wie umrechnen Float zu Real? Float = Real, da braucht man nichts rechnen.

Nimm das Bitmuster des DWORD und speichere es in eine REAL-Variable bzw. speichere es auf einen 32-Bit-Speicherplatz und hole es als REAL-Wert wieder raus.
DWord-Bitmuster in REAL-Variable speichern:
Code:
VAR
  dwVar : DWORD;            //Eingang DWORD
  pReal : POINTER TO REAL;
  rReal : REAL;             //Ausgabe REAL
END_VAR

dwVar := MyDWord;     //Bitmuster in das DWord speichern
pReal := ADR(dwVar);  //Pointer auf das DWord setzen
rReal := pReal^;      //REAL-Wert aus dem DWord in Real-Variable speichern
Oder den REAL-Wert via UNION aus Words oder Bytes zusammenbasteln:
Code:
TYPE U_REALWORDS :
  UNION
    uReal  : REAL;
    uaWord : ARRAY[0..1] OF WORD;
  END_UNION
END_TYPE

tempU : U_REALWORDS;


tempU.uaWord[0] := dasEineWord;
tempU.uaWord[1] := dasAndereWord;
rMyReal := tempU.uReal;
Code:
TYPE U_REALBYTES :
  UNION
    uReal  : REAL;
    uaByte : ARRAY[0..3] OF BYTE;
  END_UNION
END_TYPE

tempU : U_REALBYTES;


tempU.uaByte[0] := Byte_1;
tempU.uaByte[1] := Byte_2;
tempU.uaByte[2] := Byte_3;
tempU.uaByte[3] := Byte_4;
rMyReal := tempU.uReal;

Zahl: 0,627009646302255
DWORD: 1059095476
Übrigens: das Bitmuster 1059095476 dez = 16#3F2083B4 = 0.627009630203
siehe z.B. diesen IEEE-754 Konverter

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Vielen Dank für diese Ausleselösung, habe es so probiert und es funktioniert natürlich super. :-D

Was mich jetzt aber noch interessiert warum die Umwandlung nicht funktioniert hat. Es sollte ja möglich sein über das "extrahieren" der Bits und Bytes auch auf das Ergebnis zu kommen. Was habe ich da falsch gemacht das dies im 0,xxx Bereich nicht funktioniert hat:confused:.
Hat hierzu jemand eine Antwort? Mich würde mein Fehler sehr interessieren.
 
Hallo,

habe mich nochmal mit meinem Problem beschäftigt. Ich denke ich kam nicht zu einem Ergebnis, da EXPT(x,-1) mit negativen Exponenten probleme hatte :confused:. Zumindest funktionierte es nach dem ich es in
1 / EXPT(x,1) umgeschrieben hatte. Danach habe ich noch einwenig getestet und mein Ergebnis wäre unten mitzuverfolgen. Wenn jemand noch Fehler/ Verbesserungen sieht freue ich mich darüber. CLOSE ;)

Code:
//////////////////////////////////////////////////////////
//    Berechnung von Float nach Real                        
//                                                        
//    Ergebnis = Vorzeichen * Exponent * Mantisse           
//                                                        
//    Vorzeichen     = (-1)^ VZ                                
//    Exponent    = 2^(Exp-127) od. 1/(2^126)               
//    Mantisse    = 1+(Mant/(2^23)) od. (Mant/(2^23))       
//                                                        
//                                                        
//////////////////////////////////////////////////////////
ObError := FALSE;

// Vorzeichen
rVZ:= EXPT(-1, usiVorzeichen);

    //Null
IF (usiExponent = 0) AND (diMantisse = 0) THEN
    rExpo := 0;
    rManti:= 0;
    
    //denormalisierte Zahl
ELSIF (usiExponent = 0) AND (diMantisse > 0) THEN

    rManti         := (diMantisse/EXPT(2, 23));
    rExpo        := (EXPT(2, 1-127));

    //Unendlich
ELSIF (usiExponent = 255) AND (diMantisse = 0) THEN
    rExpo := 0;
    rManti:= 0;
    ObError := TRUE; (*Infinity*)
    
    //keine Zahl
ELSIF (usiExponent = 255) AND (diMantisse > 0) THEN
    rExpo := 0;
    rManti:= 0;
    ObError := TRUE; (*NaN*)

    // normalisierte Zahl
ELSE
    rManti         := 1+(diMantisse/EXPT(2, 23));
    IF (usiExponent < 127) THEN 
    rExpo        := (1/EXPT(2, 127-usiExponent));

    ELSE
    rExpo        := (EXPT(2, (usiExponent-127)));

    END_IF    
END_IF

rErgebnis    := rVZ*rManti*rExpo;

// Ergebnisausgabe
OrErgebnis:= rErgebnis;
 
Zurück
Oben