Wandlung Real zu Int

Zuviel Werbung?
-> Hier kostenlos registrieren
@ Gerhard, zunächst erst mal vielen Dank für deine Hilfe!!!!!!

Ich habe den Code 1:1 übernommen und im Moment wird das DBD0 gar nicht mehr übertragen und das nächsten Word (DBD4) kommt nach wie vor erst im übernächsten Word an. :confused:
Außerdem übertrage ich eine "1" wird die Wertigkeit "16256" im INT empfangen.

Gruß Gerhard

 
Zuviel Werbung?
-> Hier kostenlos registrieren
Und wenn nicht, bringt mir das DTB und BTI auch nichts!

doch, jetzt mal abgesehen davon, dass BTI nur -999..999 kann :rolleyes: würde eine Zahl außerhalb des Wertebereiches den Aufruf von OB121 erwirken und somit eine Fehlerbehandlung gestatten...
worauf ich hinaus wollte: bevor man den RND-Wert in ein INT quetscht sollte man vielleicht über eine bereichskonsistenzprüfung nachdenken...
 
doch, jetzt mal abgesehen davon, dass BTI nur -999..999 kann :rolleyes: würde eine Zahl außerhalb des Wertebereiches den Aufruf von OB121 erwirken und somit eine Fehlerbehandlung gestatten...
worauf ich hinaus wollte: bevor man den RND-Wert in ein INT quetscht sollte man vielleicht über eine bereichskonsistenzprüfung nachdenken...

Hatte Ich nicht gewusst, das dann ein OB aufgerufen wird (hat da auch nicht weiter drüber nachgedacht). Ich würde, wenn dies vorkommen kann, jedoch auch eine Bereichsprüfung direkt hier im Code als im OB 121 vorziehen!
 
Code:
[COLOR=red]L 0
T #index2
[/COLOR]L 0
T #index
do: NOP 0
L #index
SLD 3
LAR1 
 
[COLOR=#ff0000]L #index2[/COLOR]
[COLOR=#ff0000]SLD 3
LAR2[/COLOR]

AUF "Remote_MW"
L DBD [AR1,P#0.0]
RND 
AUF "DB LDD2"
T DBW [AR2,P#80.0]
L 2
L index2
+I
T index2
L 4
L #index
+I 
T #index
L 32
>I 
SPB end
SPA do
end: NOP 0

Mein Fehler!Beschreib den index2 auch außerhalb der Schleife mit dem Anfangswert. Wird ja immer überschrieben.
 
Kann sein das ich mich irre, aber ich glaube das bei eine "einfachen" überlauf wir "OV" gesetzt, aber OB121 wird nicht ausgeführt.
Ein test wird das abklären (wäre für mich auch interessant).

Aber wer wird mit 0..999 zufrieden ?
Problematisch ist das bei RND werden die DINT grenzen überwacht, aber nicht die INT Grenzen. Ist also nicht genügend das OV bit zu überwachen.
 
Kann sein das ich mich irre, aber ich glaube das bei eine "einfachen" überlauf wir "OV" gesetzt, aber OB121 wird nicht ausgeführt.
Ein test wird das abklären (wäre für mich auch interessant).

jesper, was meint "einfacher überlauf"? bei welcher funktion?
bei RND wäre der überlauf außerhalb des Bereiches −2.147.483.648 ... 2.147.483.647 und ja, da würde
Liegt die Zahl außerhalb des zulässigen Bereichs, werden die Statusbits OV und OS auf "1" gesetzt.
zutreffen ... damit biste aber noch nicht bei INT ...

der OB121 wird bei der funktion BTI aufgerufen
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja, darin liegt das Problem.
−2.147.483.648 ... 2.147.483.647 ist zu weit.
0 ... 999 ist sicherlich zu eng.

Bin gerade am testen um zu sehen ob man irgendwie OV auslösen kann, wenn ausserhalb von -32768 ... +32767.
 
Ja, darin liegt das Problem.
−2.147.483.648 ... 2.147.483.647 ist zu weit.
0 ... 999 ist sicherlich zu eng.

Bin gerade am testen um zu sehen ob man irgendwie OV auslösen kann, wenn ausserhalb von -32768 ... +32767.

wo du sowieso grad am testen bist:

Code:
*
      L      #zuIntZuWandelndeZahl
      L      0
      +I

sollte IMHO OV setzen, wenn #zuIntZuWandelndeZahl außerhalb des Bereiches ist
 
Prüfung ob REAL -> DINT einen gültigen INT-Wert ergibt:
Die Möglichkeit des für INT zu großen DINT-Wertes muß auf jeden Fall im Programm abgefangen werden.
Die Zwischenwandlung nach BCD verkompliziert die Sache nur und bringt zusätzlich die Gefahr des OB121-Aufrufs bzw. CPU-STOP bei BTI.

Ich würde die Übertragungs-Schleife und die INT-Prüfung etwa so machen:
Code:
//Code für FC optimiert! In FB noch AR2 + DINO sichern und wiederherstellen!
//Initialisierung Pointer und Schleifenzähler
      L     P#0.0               //Startoffset des REAL-Arrays in DB "Remote_MW"
      LAR1                      //DB + AR1: Pointer auf REAL-Array
      AUF   "Remote_MW"

      L     P#80.0              //Startoffset des INT-Arrays in DB "DB LDD2"
      LAR2                      //DI + AR2: Pointer auf INT-Array
      TDB
      AUF   "DB LDD2"
      TDB

      L     8                   //Anzahl zu übertragender Werte
      T     #loopcount          //als Startwert des Schleifenzählers

//Schleife: REAL lesen und als INT ablegen, Schleifenzähler zählt rückwärts
loop: L     DBD [AR1,P#0.0]     //REAL lesen
      RND                       //REAL -> DINT

//    prüfen ob der DINT-Wert in INT passt (-32768..0..+32767)
      PUSH                      //DINT-Wert in Akku2 merken
      ITD                       //Akku1 INT -> DINT
      ==D   
      SPB   abl

//    !Fehlerbehandlung: Wert passt nicht in INT!
      L     0                   //z.B. 0 als Ersatzwert nehmen

//    INT-Wert in Array speichern
abl:  T     DIW [AR2,P#0.0]     //INT speichern

//    alle Werte übertragen? (--Schleifenzähler <= 0 ?)
      L     #loopcount
      L     1
      -I    
      SPMZ  end
      T     #loopcount

//    beide Pointer auf nächstes Element setzen
      +AR1  P#4.0               //REAL ist 4 Byte lang
      +AR2  P#2.0               //INT ist 2 Byte lang
      SPA   loop                //Schleife wiederholen

end:  NOP   0

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Argh !

Hatte ein Fehler gemacht.
Dann wird das ergebnis leider, OV und OB121 werden beide nicht aktiviert !

Code:
      L     MD   100
      RND   
      A     OV
      JC    _er1
      L     0
      +I    
      A     OV  // korrektur !
      JC    _er2
      T     MW   110
      JU    end
_er1: S     M     10.0
      JU    end
_er2: S     M     10.1
      JU    end
end:  NOP   0
 
OB121 wird nicht ausgeführt.

die OB121-Aussage bezog sich, nochmal, auf die BTI-Funktion! :evil:

edit: Das einfache übertragen von ein wert ausserhalb -32768 ... +32767 setzt nicht OV, und OB121 wird nicht ausgeführt.
eine einfaches Übertragen? L? wie auch, hast ja die volle 32bit-breite

Ein wert grösser als +32767 rollt runter und bleibt einfach ein minus-wert.

beim test mit L 0, +I ? ...eigenartig ... was passiert bei L 1, *I ?
 
Leider dieselbe ergebnis.
Code:
      L     MD   100
      RND   
      L     1
      *I                                // versuch OV auszulösen
      A     OV
      JC    _er1
      T     MW   110
      A     OV
      JC    _er2
      JU    end
_er1: S     M     10.0                  // OV nach *I
      JU    end
_er2: S     M     10.1                  // OV nach T MW
      JU    end
end:  NOP   0
 
Code:
*
      L      #zuIntZuWandelndeZahl
      L      0
      +I

sollte IMHO OV setzen, wenn #zuIntZuWandelndeZahl außerhalb des Bereiches ist
Setzt kein OV, weil +I einfach nur die unteren 16-Bit von #zuIntZuWandelndeZahl nimmt. + 0 ergibt dann auf jeden Fall einen gültigen INT-Wert.
Wenn nach der + 0 allerdings das Ergebnis = #zuIntZuWandelndeZahl ist, dann ist #zuIntZuWandelndeZahl im für INT gültigen Bereich.

Harald
 
Zurück
Oben