Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1840to1844
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Bankers Rounding bei Prozentwerten

Bankers Rounding bei Prozentwerten
12.08.2021 20:05:42
Marco
Hallo liebes Forum,
ich stehe gerade auf dem Schlauch und hoffe, ihr könnt mir helfen. Ich möchte per VBA in einem Excel-Zellbereich Prozentzahlen mit den standardmäßigen Nachkommastellen runden zu "ganzzahligen" Prozentwerten, also bspw. 0,521234 zu 0,52. Als Besonderheit soll nicht kaufmännisch gerundet werden, sondern gemäß dem bankers rounding. Genau das sollte mit ROUND direkt gehen:

Sub BankersRounding()
Dim rngZelle As Range
Set rngZelle = ThisWorkbook.Sheets(1).Range("A1")
rngZelle.Value = Round(rngZelle.Value, 2)
End Sub
Was jetzt passiert ist folgendes: wenn in A1 der Wert 0,545 steht (also 54,5%), dann rundet ROUND klassisch kaufmännisch zu 0,55. Das ist genau nicht gewünscht, weil beim bankers rounding jeweils zur nächsten geraden Zahl (in dem Fall zum nächsten geraden "ganzen" Prozentwert) gerundet wird, d.h. das gerundete Ergebnis sollte hier 0,54 sein. Wenn in A1 dagegen der Wert 54,5 steht, dann rundet ROUND korrekt zu 54. Es hilft auch nicht, wenn man den Wert von 0,545 in A1 erst mit 100 multipliziert (was ja dann 54,5 ist), dann rundet und anschließend wieder durch 100 teilt (Ergebnis ist dann wieder 0,55). Der Unterschied besteht selbst dann, wenn ich völlig unabhängig von einer Zelle in VBA rechne:

Sub BankersRounding()
Debug.Print (Round(54.5))           'Ergebnis ist 54
Debug.Print (Round(0.545 * 100))    'Ergebnis ist 55
End Sub
Offensichtlich wird das Ergebnis der Multiplikation mit 100 anders behandelt als der erste Werte ohne Multiplikation. Die Frage wäre also, ob es einen einfachen Weg gibt das Bankers Rounding auf die Prozentzahlen anzuwenden, ohne die Prüflogik der Rundungsmethode in mehreren Schritten nachbauen zu müssen?
Vielen Dank für eure Gedanken,
Marco

14
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
Mathematisches Runden
12.08.2021 20:36:52
lupo1
... ist schon richtig mit ROUND. Du musst aber die Zahl dafür korrekt skalieren. Probiere Dich da mal selbst aus.
AW: Mathematisches Runden
13.08.2021 09:06:25
Marco
Hi Lupo1,
danke für den Hinweis (und danke an alle für den Input). Nach einigem Probieren scheint es zu funktionieren, wenn ich den Wert vor dem Runden in eine double oder decimal konvertiere:

Sub BankersRounding()
ActiveSheet.Range("A1").Value = Round(CDbl(ActiveSheet.Range("A1").Value), 2)
End Sub
Ist es das, was du gemeint hast?
LG & danke,
Marco
Hab mir da jetzt nicht den Kopp dazu gemacht ...
13.08.2021 09:58:37
lupo1
... aber das CDbl sieht ganz gut aus.
Da Excel (mit dem einzigen Typ Variant) eher als VBA (mehrere Typen) in einen Gleitkommafehler hineinläuft, wäre dort möglicherweise die Stack-Overflow-Formel noch anzupassen.
Anzeige
Statt CDbl ...
13.08.2021 10:09:59
lupo1
... könnte man Deine Werte auch *200*10^x transformieren und dann mit CInt arbeiten.
Das hätte den Vorteil, dass Du die Gleitkommageschichte selbst definierst, statt dies CDbl zu überlassen.
Das x wäre dabei die gewünschte Genauigkeit, vermutlich 6 bis 8.
AW: Statt CDbl ...
13.08.2021 13:01:46
Marco
Hi,
vielen Dank schon mal...auch auf die Gefahr hin, dass ich mich jetzt komplett als Anfänger in Sachen Variablentypen in VBA oute: mich interessiert hier ja nur die Rundung in der dritten Nachkommastelle, also bspw. 0,545 soll zu 0,54 = 54% gerundet werden. Zwischen 0% und 100% gibt es also nur 100 Werte, die nach Bankers Rounding korrekt gerundet werden sollen: 0.005, 0.015, 0.025 etc. Testweise habe ich die 100 Werte per Formel inkl. der dazugehörigen gerundeten Werte erzeugt (https://www.herber.de/bbs/user/147606.xlsx) und dann den Ausgangswert noch einmal per VBA in drei Varianten mit ROUND gerundet (ohne Konvertierung, mit CDbl und mit CDec):

Sub BankersRounding()
Dim rng As Range: Set rng = ThisWorkbook.Sheets("Test").Range("A2:A101")
Dim zeile As Integer: zeile = 2
Dim wert As Variant
For Each wert In rng
With ThisWorkbook.Sheets("Test")
.Cells(zeile, 4).Value = Round(wert.Value, 2)
.Cells(zeile, 5).Value = Round(CDbl(wert.Value), 2)
.Cells(zeile, 6).Value = Round(CDec(wert.Value), 2)
End With
zeile = zeile + 1
Next wert
End Sub
Stellt sich raus, dass die Konvertierung mittels CDbl bei zwei Zahlen, und nur bei denen, das falsche Ergebnis liefert: 0.545 wird zu 0.55 und 0.575 zu 0.57 gerundet. Beim Konvertieren mittels CDec passiert das allerdings nicht...alle anderen Werte werden in allen drei Varianten korrekt gerundet. Macht das Sinn?
Anzeige
Lies Dich ein: Gleitkommaproblematik
13.08.2021 13:13:16
lupo1
Du musst also die Ausgangszahl erst mal ein wenig frisieren, bevor Du sie behandelst.
Das habe ich ebenfalls festgestellt, ...
14.08.2021 00:06:37
Luc:-?
…Marco,
und könnte lt Lupos Link tatsächlich an der GleitkommaProblematik liegen. Im Endeffekt bleibt hier aber auch Round symmetrisch, da einer falschen Aufrundung eine falsche Abrundung ggübersteht, nur nicht so regelmäßig wie es eigentl sein sollte. Regelmäßiger ist da tatsächlich Lupos korrigierte 2.Fml, falls alle Zahlen physisch nur 3 Dezimalen haben, deren letzte 5 ist.
Morhn, Luc :-?
=ABRUNDEN(A1;2)
12.08.2021 21:40:04
WF
.
Da WF auf dem VBA-Auge blind sein will ...
13.08.2021 01:52:40
lupo1
... und bei excelformeln.de anscheinend niemand das "mathematische (oder Bankers) Runden" (i Ggs z kfm Runden) im Blick hatte:
=ABRUNDEN(A1;2)+(REST(A1/1%;1)=0,5)*REST(ABRUNDEN(A1;2)/1%;2)%
... geht vielleicht noch kürzer (oder mittlerweile evtl. auch durch eine eigene Tabellenfunktion?).
Zahl ... wird zu
5,465 5,46
5,475 5,48
5,485 5,48
5,495 5,50

Rein statistisch ist das Landen bei einem halben Cent unrelevant, da stetig mit einer Wkt. von Null. Tatsächlich ist es aber so, dass viele Betrags-Summen nur durch 2 geteilt werden, und dann würde der Cent immer nur gleich gerundet, je nach verwendeter Rundungsvorschrift. Und das kann systematisch einer Bank eben nicht schmecken. Ein genau halber Cent ist nämlich außerordentlich "diskret gewichtig, mit hoher Wahrscheinlichkeit", so dass man ihn deswegen hälftig nach oben und nach unten runden muss.
Bei VBA gibt es daher die EIGENE Funktion Round(), die math./bankermäßig wie oben rundet.
Die Excelfunktion RUNDEN wird hingegen als WorksheetFunction.Round() verwendet (kfm. Runden wie gewohnt).
Anzeige
Ja, so etwas habe ich gemeint, ...
13.08.2021 02:35:53
Luc:-?
…wobei Deine Erklärung für die Round-Arbeitsweise logisch treffender ist, denn sie fktioniert immer und andere Zahlen müssen nicht berücksichtigt wdn. Also, ist die letzte anzuzeigende Dezimale ursprüngl gerade, wird ab-, ist sie ungerade, aufgerundet, falls der ursprüngl nachfolgenden 5 keine weitere Dezimale >0 folgt. Allerdings erklärt das nicht, warum hier 0,545 zu 0,55 aufgerundet wird. Da wdn sich wohl doch noch weitere Dezimalen eingeschlichen haben…
In Korrektur zu meinem unteren Beitrag muss ich noch bemerken, dass nur eine folgd 0 nicht reicht, es darf innerhalb der möglichen Berechnungsbreite* unter den der 5 ggf nachfolgd Dezimalen keine von 0 verschiedene auftreten, also Periode 0.
* Normalerweise 15 Ziffernstellen, bei Variant-Umwandlung mit CDec fast doppelt so viele.
Morhn, Luc :-?
Anzeige
Es geht um die "Breite der Zahl x,xx5" von Null
13.08.2021 03:11:54
Null
und dafür steht REST(A1/1%;1)=0,5
Meine Formel ist falsch
13.08.2021 03:56:06
lupo1
... da sie sich nicht auf x,xx5 beschränkt. Es geht aber nur um diesen Wert.
https://stackoverflow.com/questions/44310679/bankers-rounding-formula-in-excel
=IF(AND(ISEVEN(A1*10^0),MOD(A1*10^0,1)&lt=0.5),ROUNDDOWN(A1,0),ROUND(A1,0))
müsste abgewandelt für den Cent-Fall sein:
=WENN(ISTGERADE(A1/1%)*(REST(A1/1%;1)&lt=0,5);ABRUNDEN(A1;2);RUNDEN(A1;2))
mathematisch runden hab ich noch nie gehört
13.08.2021 07:46:09
WF
mea culpa - Fundstellen gibt's genug
Das kann auch richtig sein, ...
13.08.2021 02:15:25
Luc:-?
…Marco,
denn es gibt nur 2 „normale“ Rundungsmethoden (neben generellem Abrunden/Kürzen bzw Aufrunden), asymmetrisches („kaufmännisches“) und symmetrisches (mathematisch-naturwissenschaftliches, auch von Bankern verwendetes Runden). Bei letzterem wird bei nachfolgender 5 versucht, einen symmetrischen Ausgleich zu schaffen. Folgt dieser 5 eine 1 wird aufgerundet, folgt ihr eine 0 idR abgerundet. Ist die Anzahl der Dezimalen ungleich, kann die Genauigkeit nicht größer sein als 1 Dezimale weniger als die kleinste DezimalenAnzahl. 0,521234 wird demzufolge zu 0,52; 0,545 kann aber auch zu 0,55 statt 0,54 wdn, das hängt ggf auch von den anderen Zahlen ab (speziell bei MatrixFmln und VBA-Berechnung ganzer %-Blöcke) und natürlich davon, ob weitere Dezimalen nicht nur unterdrückt wurden. %-Format entspricht dabei einer vorangegangenen Division durch 100, die bei der Anzeige berücksichtigt wird. Schreibt man dagegen 54,5% in eine Zelle, wird die Division durchgeführt und der eigentliche Zellwert lautet 0,545, der in Xl idR automatisch als %-Zahl formatiert wird. Xl rundet allerdings asymmetrisch. Willst du Xl dazu bringen, symmetrisch zu rechnen, musst du eine UDF mit der vbFkt Round in Xl-Fmln verwenden, die ggf auch noch einen ganzen Zahlenblock einbezieht und so eine bessere Symmetrie schafft. Mit einer SubProzedur wäre das ggf auch möglich.
Morhn, Luc :-?
„Der beste Beweis für intelligentes Leben im Universum ist, dass noch niemand versucht hat, Kontakt mit uns aufzunehmen.“ H.Lesch, 2018, Sonneberg
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige