Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Banker's Rounding 2,45 --> 2,4 ?????
blade_51
myCSharp.de - Member



Dabei seit:
Beiträge: 4

Themenstarter:

Banker's Rounding 2,45 --> 2,4 ?????

beantworten | zitieren | melden

Hallo,

da Math.Round den Wert 2,45 auf 2,4 abrundet und nicht aufrundet, such ich eine Klasse die nicht nach diesem Prinzip arbeitet. Vielleicht hat sich da einer schon mal mit beschäftigt und kann mir weiterhelfen?

Gruß Sebastian
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo blade_51,

bei Math.Round einfach noch MidpointRounding.AwayFromZero angeben.

herbivore
private Nachricht | Beiträge des Benutzers
blade_51
myCSharp.de - Member



Dabei seit:
Beiträge: 4

Themenstarter:

beantworten | zitieren | melden

hat super funktioniert. Ich war schon dabei mir eine eigene Klasse zu basteln 'lol. Ich bedank mich.

mfg Sebastian
private Nachricht | Beiträge des Benutzers
TEry
myCSharp.de - Member



Dabei seit:
Beiträge: 98

beantworten | zitieren | melden

Unabhängig davon, dass es so funktioniert, sollte man im Auge behalten, das in diesem Beispiel alle geraden Zahlen vor 0.05 , also 0.4 abgerundet und alle ungeraden Zahlen vor 0.05, 0.5 aufgerundet werden.
Siehe Beispiel unten:
1.45 = 1.4
1.55 = 1.6

Eine Tatsache die man im Hinterkopf behalten sollte. MidpointRounding.ToEven gibt dabei auch 1.4 und 1.6 aus.

Fals also eine Abrundung nötig ist, funktionieren die dazu nötigen Routinen nicht.
Doch wer wünscht schon eine Abrundung


double d = 1.45;
d = Math.Round(d, 1 );
richTextBox1.AppendText(d.ToString() + "\n");

d = 1.55;
d = Math.Round(d, 1 );
richTextBox1.AppendText(d.ToString() + "\n");

Gruss TEry
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo TEry,

ich verstehe nicht worauf du hinaus willst. Ohne Angabe von MidpointRounding und bei Angabe MidpointRounding.ToEven funktioniert Math.Round, wie du geschrieben hast:

1.45 = 1.4
1.55 = 1.6

Und mit Angabe von MidpointRounding.AwayFromZero funktioniert Math.Round nach kaufmänischer Rundung:

1.45 = 1.5
1.55 = 1.6

Das ist aber gerade das Thema des Threads und war schon geklärt. Übersehe ich etwas?

herbivore
private Nachricht | Beiträge des Benutzers
TEry
myCSharp.de - Member



Dabei seit:
Beiträge: 98

beantworten | zitieren | melden

Hallo herbievore,

geklärt wohl schon, aber nicht erklärt.

Es ist im Prinzip doch eine Frage der Regelmässigkeit.
Wenn ich 2 Zahlen habe, die so nahe aufeinanderliegen wie 1.45 und 1.55 und bekomme von Math.Round einmal:
1.4
und nachher
1.6
Ich nenne das Horror und da muss man sich doch einmal fragen wieso!!!
Wieso wird der Wert einmal abgerundet wird und einmal aufgerundet.

Ist das eine Laune der Natur, oder ein Zaubertrick?

Das gibt eine Differenz von 0.2. Und sollten wir Angesicht's dieser Resultate einfach sagen: Nimm doch MidpointRounding.AwayFromZero.

Das ist natürlich eine Lösung auf die Schnelle aber manch einer übersieht dabei etwas! Das Problem liegt tiefer. Und zwar im Inneren des Fliesskomma Prozessors, welcher die geraden Bits gerade sein lässt und diese kleine Differenz bewirkt diese enormen Schwankungen.

Ich finde das übel! Der Compiler arbeitet aufgrund des Coprozessors nicht zuverlässig und man deckt diesen Mangel lediglich zu, anstatt ihm auf den Grund zu gehen.
Eine Abrundung jedenfals ist auf Basis von Regelmässigkeit mit Math.Round nicht möglich. Und dann ist basteln angesagt.

Aber sry: Es ging hier ja um kaufmännische Roundung. Ich wollte nur nicht, das jemand denkt, die Round Problemetik sei damit gelöst. Aber wahrscheinlich intressiert das niemanden. Ich für meinen Teil habe euch jedoch gewarnt. Sagt dann nicht: Wieso hat TEry nix gesagt ...


Gruss TEry
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo TEry,

du unterstellst, Round würde aufgrund eines Fehlers im Fliesskommaprozessor falsch Runden. Das ist nicht der Fall!

Es gibt eben verschiedene Verfahren zu runden. In Amerika ist es anscheinend sehr beliebt, auf gerade Zahlen zu runden. Deshalb ist Round auch default-mäßig so implementiert. In Europa oder zumindest in Deutschland ist kaufmännische Rundung beliebter. Deshalb bietet das Framework ab der Version 2.0 auch die Möglichkeit, sich das Verfahren der Rundung auszusuchen: ToEven oder AwayFromZero.

Also kein Zaubertrick!

herbivore
private Nachricht | Beiträge des Benutzers
TEry
myCSharp.de - Member



Dabei seit:
Beiträge: 98

beantworten | zitieren | melden

hi herbievore,

nö, das ist kein Fehler im Fliesskommaprozessor! Das ist der Aufbau des Prozessors. Das ist lediglich die Problemetik der 0 und 1 im Inneren des Prozessors. Das Bit, welches die 111 = 5 vom geraden oder ungeraden Wert, der davor liegt = 0 oder 1 dazubestellt bekommt, beinflusst die Rundung. Daher ungerade Zahl = aufrunden Gerade Zahl, abrunden.

gut das niemand weiss, das ich Rumpelstilzchen heiss

Gruss TEry

ps. Zudem funktioniert ToEven auch auf diesem Prinzip
Resultate:

1.4
1.6
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo TEry,

die "Round-to-even method" ist aber älter als der Fliesskommaprozessor. Wikipedia sagt, dass diese Methode seit 1940 (ein bestimmter) Standard ist. Zu der Zeit gab es nicht mal Transistoren. Oder anderes gesagt, die Amis wollen gerne so runden.
Zitat
Der Compiler arbeitet aufgrund des Coprozessors nicht zuverlässig und man deckt diesen Mangel lediglich zu, anstatt ihm auf den Grund zu gehen.
Davon kann also keine Rede sein.

herbivore
private Nachricht | Beiträge des Benutzers
TEry
myCSharp.de - Member



Dabei seit:
Beiträge: 98

beantworten | zitieren | melden

Hallo herbievore,

ich kann dir auch nicht genau sagen, wo der Fliesskommaprozessor die Roundung hernimmt. Doch die Erklärung liegt nahe, das bei einem bestimmten Vorzeichen die Roundung einmal so, dann wieder so ausfällt. Wie willst du mir dann erklären, das alle mit geraden Zahlen also 0.05 0.25 0.45 0.65 0.85 abgerundet und alle auf ungerade Vorzeichen 0.15 0.35 0.55 0.75 0.95 gefolgte Zahlen aufgerundet werden.
Das liegt einzig im Inneren des Fliesskommaprozessors und der Gleichgültigkeit der Entwickler von Compiliers. Immerhin haben sie ja die MidpointRounding.AwayFromZero sauber implementiert. Jedoch fehlt eine Abrundung von
1.45
1.55
auf
1.4
1.5

Gruss TEry.

ps. Möglicherweise liegt es auch einfach in der Begrenzung der Register auf eine gewisse Menge. Hätten wir unendlich grosse Prozessorregister, könnte die Roundung theoretisch gleichmässig sein. Aber die FPU ist nun mal ein Werk von Nullen und Einsen, und somit Menschenhand und damit notwendigerweise auf ein wenig Nacharbeit angeweissen.
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo TEry,
Zitat
ich kann dir auch nicht genau sagen, wo der Fliesskommaprozessor die Roundung hernimmt.
ich gebe es auf. Ich habe mehrfach geschrieben, dass es Absicht ist, dass Round-To-Even verwendet wird. Wenn du meinst, dass es eine Laune der Natur ist, bitte, dann werde glücklich damit.

herbivore
private Nachricht | Beiträge des Benutzers
progger
myCSharp.de - Member

Avatar #avatar-2094.gif


Dabei seit:
Beiträge: 1.271
Herkunft: Nähe von München

beantworten | zitieren | melden

Hallo TEry,

Irgendwie hab ich das Gefühl, du WILLST das ganze nicht verstehen.
Es ist ABSICHT, dass so gerundet wird, weil es ist einfache eine ART der Rundung. Ich möchte jetzt nicht weiter ausschweifen, am besten informierst du dich selbst. Wikipedia ist dein Freund: Rundung -> Unverzerrte Rundung.

Ich hoffe das leuchtet dir jetzt ein.

Gruß,
Thomas
A wise man can learn more from a foolish question than a fool can learn from a wise answer!
Bruce Lee

Populanten von Domizilen mit fragiler, transparenter Außenstruktur sollten sich von der Translation von gegen Deformierung resistenter Materie distanzieren!
Wer im Glashaus sitzt, sollte nicht mit Steinen werfen.
private Nachricht | Beiträge des Benutzers
TEry
myCSharp.de - Member



Dabei seit:
Beiträge: 98

beantworten | zitieren | melden

Ich verstehe die Rundungsproblematik. Nur ist in graphischen Darstellungen eine gewisse Regelmässigkeit notwendig und da nützt mir die IEEE 754 Norm herzlich wenig. Da kann ich nicht einmal einen Wert von 1.4 und 1.6 brauchen. Und das ist das Problem. Ich denke jedoch das die IEEE 754 Norm lediglich die internen Probleme des Prozessors verschleiert. Aber ich möchte jetzt keine sogenannte Verschwörungstheroie zur Sprache bringen. Zudem habe ich für Abrunden der Zahlen ja meine Routine geschrieben, und was ihr braucht habt ihr ja auch.

Also sind wir alle glücklich und beste Wünsche

TEry
private Nachricht | Beiträge des Benutzers