Step 7 Mit einem SCL Programm auf 0 oder 5 runden

Wellermann

Level-1
Beiträge
24
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo ihr im Forum,

ich benötige eure Hilfe. Ich muss eine die letzte Stelle einer Zahl auf 0 oder 5 runden. Das ganze sieht in etwa so aus:
Ich möchte einen SCL Baustein dafür schreiben eine DINT Zahl rein und eine DINT Zahl wieder raus.

Eigentliche Zahl | gerundet
241 | 240
353 | 350
154 | 150
456 | 460
379 | 380

Habt ihr da eine Idee für mich??

schönen Gruß
Mirko:p
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
in deinem Beispiel möchtest du anscheinend auf ganze Zehner runden. Das ist recht einfach :
Code:
myNeuInt := 10 * ((myOriginalInt + 5) / 10) ;

Selbstverständlich lassen sich auf die Weise auch noch andere Rundungsschritte realisieren ...

Gruß
Larry
 
Das einfache Verfahren mit /10*10 kann man anwenden, wenn der tatsächlich mögliche Wertebereich des Eingangswertes begrenzt ist, weil das Verfahren am unteren und am oberen Ende des INT/DINT-Wertebereiches völlig falsche Ergebnisse liefert, weil ein Aufrunden da nicht möglich ist. Das Addieren von 5 vor der Division schränkt den zulässigen Wertebereich noch ein klein wenig mehr ein. Und man muß hoffen, daß die SCL-Compilerbauer niemals auf die Idee kommen, daß das /10*10 zur Optimierung zusammengefasst werden könnte.

Hier ein Beispiel für Runden auf Endziffer 0 oder 5, welches für den kompletten Wertebereich von DINT funktioniert:
Code:
FUNCTION FC_RND5 : DINT
VAR_INPUT
  IN : DINT;
END_VAR
VAR_TEMP
  tmp_dDigit : DINT;
END_VAR

IF IN = -2147483648 THEN          //(-2147483648 = 16#8000_0000)
  FC_RND5 := -2147483645;         //Runden zu -2147483650 wäre außerhalb DINT-Wertebereich
ELSE
  tmp_dDigit := IN MOD 5;                          //letzte/Einer-Ziffer Basis 5 (0..4 mit Vorzeichen)
//  FC_RND5 := IN - tmp_dDigit + tmp_dDigit/3*5;   //so besser verstehbar: Wert abrunden + eventuell aufrunden
  FC_RND5 := tmp_dDigit/3*5 - tmp_dDigit + IN ;    //doch umgestellt wird 10 Byte kürzer compiliert
END_IF;
END_FUNCTION

Harald
 
also ich habe nochmal Rücksprache gehalten. So soll wie folgt programmiert sein:
241 -> 245
353 -> 355
154 -> 155
456 -> 460
379 -> 380
355 -> 355
400 -> 400

also immer Aufrunden.


Gruß
Mirko
 
Man könnte also auch gleich übersichtlich und exakt schreiben:
Code:
letzte Ziffer --> runden zu
--------------------------------
1, 2, 3, 4    --> 5 (aufrunden)
5             --> 5 (übernehmen)
6, 7, 8, 9    --> 0 (aufrunden)
0             --> 0 (übernehmen)

Harald
 
es gibt an dieser Stelle keine negativen Zahlen
Soso, sowas hört man häufig. Genau wie "der Divisor kann an dieser Stelle nicht 0 werden" oder "ein INT reicht für die Berechnung völlig aus" ... ;)
Oder https://de.wikipedia.org/wiki/Liste_von_Programmfehlerbeispielen
Beim Kampfflugzeug F-16 brachte der Autopilot das Flugzeug in Rückenlage, wenn der Äquator überflogen wurde. Dies kam daher, dass man keine „negativen“ Breitengrade als Eingabedaten bedacht hatte.

Schreib' Dir wenigstens im Kommentar Deines Programmes dazu, daß die von Dir favorisierte umständliche Lösung nicht mit negativen Zahlen klar kommt. Für den Fall, daß doch mal jemand die "getestete und schon ewig verwendete Funktion" auch für negative Zahlen nutzen will ...

PS: Eigentlich schade, daß Du hier bei der Lösungs-Findung so wenig Dein eigenes Hirn eingesetzt hast und lediglich die erste scheinbar funktionierende Lösung abgreifst. Wo bleibt denn da der Lerneffekt? :(

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
[...]
PS: Eigentlich schade, daß Du hier bei der Lösungs-Findung so wenig Dein eigenes Hirn eingesetzt hast und lediglich die erste scheinbar funktionierende Lösung abgreifst. Wo bleibt denn da der Lerneffekt? :(
[...]

Du hast ja schon recht, dass die Lösung mit der Division schöner ist, aber "scheinbar funktionierende" hat schon ein wenig mein kleines Ego verletzt :cry:
 
Zurück
Oben