Autor Thema: Kaufmännisches Runden, Lotus Script und Ratlosigkeit  (Gelesen 2960 mal)

Offline Riccardo Virzi

  • Junior Mitglied
  • **
  • Beiträge: 66
Ich möchte eine Zahl kaufmännisch Runden und schaffe das nicht unter allen Umständen in Lotus Script korrekt zu programmieren.

Dafür gibt es ja den Befehl Round. Da ist aber, meiner Meinung nach, in der Doku schon ein Fehler drin, den ich reproduzieren kann:
' Round to one decimal place.
Print Round(4.23, 1)                    ' Prints 4.2      -> RICHTIG
Print Round(4.35, 1)                    ' Prints 4.4      -> RICHTIG
Print Round(4.45, 1)                    ' Prints 4.4      ->  ??? FALSCH, sollte eigentlich 4.5 ausgeben, oder?

Damit kann ich den Round Befehl nicht nutzen. Deswegen mache ich bisher in meiner Programmierung folgendes:
1. verschiebe das Komma nach rechts durch Multiplikation mit 100 (für 2 Nachkommastellen, bei 3 Stellen muß 1000 genommen werden, usw.)
2. danach addiere ich 0,5
3. mit dem Skript Befehl Fix entferne ich die Nachkommastellen
4. verschiebe das Komma nach links durch Division mit 100 (für 2 Nachkommastellen, bei 3 Stellen muß 1000 genommen werden, usw.)

Code:
Fix( ( Wert * 100 ) + 0,5 ) / 100

Das funktioniert schon seit fast 2 Jahrzehnten gut. Bis ich eine Beschwerde Anfang der Woche bekommen habe, daß die MWSt. nicht korrekt berechnet wird.
Zu meinem Erstaunen, mußte ich festellen, daß tatsächlich der Cent Betrag nicht ok ist. Ich kann aber keinen Fehler in meiner Logik entdecken, bzw. bin ratlos wie ich den Fehler lösen soll.
Zum besseren Verständniss warum ich ratlos bin, habe ich 4 Beispiele und den Code zum Test angehängt.

Ein Beispiel mit dem Wert 64,3652 (gerundet 64,37):
   64,3652 * 100   = 6436,52
   6436,52 + 0,5   = 6437,02
   Fix( 6437,02 )   = 6437
   6437 / 100        = 64,37

Alles ok soweit. Dann schaun wir mal was mit 64,365 passiert (gerundet 64,37):
   64,365 * 100    = 6436,5
   6436,5 + 0,5    = 6437
   Fix( 6437 )       = 6436           ???
   6436 / 100       = 64,36

Ups, nicht mehr so gut. Dasselbe mache ich mal mit dem Wert 64,2652 (gerundet 64,27):
   64,2652 * 100   = 6426,52
   6426,52 + 0,5   = 6427,02
   Fix( 6427,02 )   = 6427
   6427 / 100        = 64,27

Alles ok soweit. Dann schaun wir mal was mit 64,265 passiert (gerundet 64,27):
   64,265 * 100    = 6426,5
   6426,5 + 0,5    = 6427
   Fix( 6427 )       = 6427
   6427 / 100       = 64,27

Auch alles gut! Ob mir jemand das Verhalten erklären kann, weiß ich nicht. Aber vielleicht gibt es andere Möglichkeiten die ich noch nicht bedacht habe.

Wer bis hier gekommen ist  ;D und sich dann meine Beispiele ansieht, der könnte sich folgendes fragen: warum nimmt der eigentlich Fix und nicht CInt um eine Zahl mit Nachkommastellen in eine Zahl ohne Nachkommastellen umzuwandeln?
Ganz einfach: das hatte ich tatsächlich damals programmiert, bis ein Fall aufgetreten ist, in dem der Befehl CInt/CLng ähnlich falsch reagiert hat. Die Zahl finde ich leider nicht mehr und frage deswegen bei Euch, ob das Problem beim Runden bekannt ist und jemand Ideen hat.

Hier ist ein Skript Code Beispiel, mit dem das Verhalten geprüft werden kann:
   Dim WertOriginal As Double
   Dim WertGerundet As Double
   
   WertOriginal = 64.3652
   WertGerundet = Fix( ( WertOriginal * 100.0 ) + 0.5 ) / 100      ' WertGerundet = 64,37 = RICHTIG

   WertOriginal = 64.365
   WertGerundet = Fix( ( WertOriginal * 100.0 ) + 0.5 ) / 100      ' WertGerundet = 64,36 = FALSCH
   
   WertOriginal = 64.2652
   WertGerundet = Fix( ( WertOriginal * 100.0 ) + 0.5 ) / 100      ' WertGerundet = 64,27 = RICHTIG

   WertOriginal = 64.265
   WertGerundet = Fix( ( WertOriginal * 100.0 ) + 0.5 ) / 100      ' WertGerundet = 64,27 = RICHTIG
   

Nochmal ein Beispiel mit den Befehlen Round, CDbl, CInt und DLng:
   Dim WertOriginal As Double
   Dim WertGerundet As Double
   
   WertOriginal = 64.3652
   WertGerundet = Round( WertOriginal, 2 )               ' WertGerundet = 64,37 = RICHTIG
   WertGerundet = Fix( ( WertOriginal * 100.0 ) + 0.5 ) / 100      ' WertGerundet = 64,37 = RICHTIG
   WertGerundet = CDbl( ( ( WertOriginal * 100.0 ) + 0.5 ) / 100 )   ' WertGerundet = 64,3702 = RICHTIG aber nicht gerundet
   WertGerundet = CInt( ( ( WertOriginal * 100.0 ) + 0.5 ) ) / 100   ' WertGerundet = 64,37 = RICHTIG
   WertGerundet = CLng( ( ( WertOriginal * 100.0 ) + 0.5 ) ) / 100   ' WertGerundet = 64,37 = RICHTIG
   
   WertOriginal = 64.365
   WertGerundet = Round( WertOriginal, 2 )               ' WertGerundet = 64,36 = FALSCH
   WertGerundet = Fix( ( WertOriginal * 100.0 ) + 0.5 ) / 100      ' WertGerundet = 64,36 = FALSCH
   WertGerundet = CDbl( ( ( WertOriginal * 100.0 ) + 0.5 ) / 100 )   ' WertGerundet = 64,37 = RICHTIG
   WertGerundet = CInt( ( ( WertOriginal * 100.0 ) + 0.5 ) ) / 100   ' WertGerundet = 64,37 = RICHTIG
   WertGerundet = CLng( ( ( WertOriginal * 100.0 ) + 0.5 ) ) / 100   ' WertGerundet = 64,37 = RICHTIG
   
   WertOriginal = 64.2652
   WertGerundet = Round( WertOriginal, 2 )               ' WertGerundet = 64,27 = RICHTIG
   WertGerundet = Fix( ( WertOriginal * 100.0 ) + 0.5 ) / 100      ' WertGerundet = 64,27 = RICHTIG
   WertGerundet = CDbl( ( ( WertOriginal * 100.0 ) + 0.5 ) / 100 )   ' WertGerundet = 64,2702 = RICHTIG aber nicht gerundet
   WertGerundet = CInt( ( ( WertOriginal * 100.0 ) + 0.5 ) ) / 100   ' WertGerundet = 64,27 = RICHTIG
   WertGerundet = CLng( ( ( WertOriginal * 100.0 ) + 0.5 ) ) / 100   ' WertGerundet = 64,27 = RICHTIG

   WertOriginal = 64.265
   WertGerundet = Round( WertOriginal, 2 )               ' WertGerundet = 64,26 = FALSCH
   WertGerundet = Fix( ( WertOriginal * 100.0 ) + 0.5 ) / 100      ' WertGerundet = 64,27 = RICHTIG
   WertGerundet = CDbl( ( ( WertOriginal * 100.0 ) + 0.5 ) / 100 )   ' WertGerundet = 64,27 = RICHTIG
   WertGerundet = CInt( ( ( WertOriginal * 100.0 ) + 0.5 ) ) / 100   ' WertGerundet = 64,27 = RICHTIG
   WertGerundet = CLng( ( ( WertOriginal * 100.0 ) + 0.5 ) ) / 100   ' WertGerundet = 64,27 = RICHTIG

Offline CarstenH

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 642
  • Geschlecht: Männlich
Re: Kaufmännisches Runden, Lotus Script und Ratlosigkeit
« Antwort #1 am: 14.08.20 - 22:09:41 »
Zuerst einmal - die Round() Funktion im Lotus Script führt das mathematische und nicht das kaufmännische Runden durch, das ist in der Doku auch so beschrieben: If the first non-significant digit is 5, and all subsequent digits are 0, the last significant digit is rounded to the nearest even digit.

Für die kaufmännische Version und auch die Probleme mit den Double-Variablen gab es hier vor längerer Zeit schon einmal einen Thread hier der auch eine Lösung in Form einer doppelten Konvertierung nannte, vielleicht löst das ja dein Problem:

https://atnotes.de/index.php/topic,53931.msg350309.html#msg350309

HTH
Carsten

Offline ronka

  • Senior Mitglied
  • ****
  • Beiträge: 377
  • Was macht der hier denn, muß der überall sein ?
    • das nächste DominoCamp kommt in Juni 2023
Re: Kaufmännisches Runden, Lotus Script und Ratlosigkeit
« Antwort #2 am: 16.08.20 - 12:58:15 »
,365 = ,364999999999999

Und damit geht es schief.
« Letzte Änderung: 16.08.20 - 13:05:21 von ronka »
das neueste von Notes und Domino auf den DominoCamp vom 19 bis 21 Juni 2023 auf www.DominoCamp.de

Offline Riccardo Virzi

  • Junior Mitglied
  • **
  • Beiträge: 66
Re: Kaufmännisches Runden, Lotus Script und Ratlosigkeit
« Antwort #3 am: 16.08.20 - 16:07:25 »
Danke an Carsten und Rudi für Eure Antworten.

@Carsten: es scheint der richtige Weg zu sein, eine doppelte Konvertierung zuerst zu einem String und dann zurück in eine Zahl zu machen. Das muß ich nochmal testen und werde in den nächsten Tagen eine Rückmeldung geben.

@Rudi: ich sehe das ähnlich, intern werden manche Zahlen durch Konvertierungen leicht verändert. Das wirkt sich sehr selten auf das sichtbare Ergebniss aus.

An alle, die wie ich nur den Befehl Fix einsetzen: funktioniert ganz gut aber nicht immer. Im Forum gibt es ja einige Einträge zu dem Thema. Aber keines davon konnte mein Problem lösen. Das mit der Konvertierung in einen String und zurück in eine Zahl von Carsten, habe ich entweder nicht gesehen oder nicht verstanden.

Offline billygates

  • Aktives Mitglied
  • ***
  • Beiträge: 145
  • Geschlecht: Männlich
  • Ich kann 'proprietär' nicht mehr hören!
Re: Kaufmännisches Runden, Lotus Script und Ratlosigkeit
« Antwort #4 am: 28.08.20 - 09:30:32 »
Wie wäre es mit @Round in der Formelsprache?

Offline CarstenH

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 642
  • Geschlecht: Männlich
Re: Kaufmännisches Runden, Lotus Script und Ratlosigkeit
« Antwort #5 am: 28.08.20 - 10:34:01 »
Wie wäre es mit @Round in der Formelsprache?

Die verschiedenen Programmiersprachen verhalten sich hier gleich, das ist auch in der Dokumentation so nachzulesen.
Das hatte ich auch gleich zu Beginn meines ersten Tests vorsichtshalber überprüft ;)

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz