77 Stimmen

Float oder Dezimal für den Dollarbetrag der Buchhaltungsanwendung verwenden?

Wir schreiben unser Erbe neu Buchhaltungssystem in VB.NET und SQL Server. Wir haben ein neues Team von .NET/SQL-Programmierern mit der Neufassung beauftragt. Der größte Teil des Systems ist bereits fertiggestellt, wobei die Dollarbeträge mit Fließkommazahlen angegeben werden. In der Sprache des Altsystems, in der ich programmiert habe, gab es keine Fließkommazahlen, also hätte ich wahrscheinlich eine Dezimalzahl verwendet.

Was ist Ihre Empfehlung?

Sollte für Dollarbeträge der Datentyp Float oder Dezimal verwendet werden?

Was sind die Vor- und Nachteile der beiden?

Eine con erwähnt in unserem tägliches Scrum war, dass Sie vorsichtig sein müssen, wenn Sie einen Betrag berechnen, der ein Ergebnis mit mehr als zwei Dezimalstellen ergibt. Es klingt, als müssten Sie den Betrag auf zwei Dezimalstellen runden.

Eine weitere con ist, dass alle Anzeigen und gedruckten Beträge mit einem Formatanweisung die zwei Dezimalstellen anzeigt. Mir ist aufgefallen, dass dies in einigen Fällen nicht der Fall war und die Beträge nicht korrekt aussahen. (z. B. 10,2 oder 10,2546)

A pro ist, dass die reine Fließkommazahl acht Bytes auf der Festplatte benötigt, während die Dezimalzahl neun Bytes beanspruchen würde (Dezimalzahl 12,2).

7 Stimmen

Gehen Sie zurück und werden Sie Ihre Schwimmer los.

112voto

TSK Punkte 1126

Sollte für Dollarbeträge der Datentyp Float oder Decimal verwendet werden?

Die Antwort ist einfach. Schwimmt nie. NIEMALS !

Die Schwimmer waren nach IEEE 754 immer binär, nur der neue Standard IEEE 754R definierte Dezimalformate. Viele der gebrochenen Binärteile können niemals der exakten Dezimaldarstellung entsprechen.

Jede Binärzahl kann geschrieben werden als m/2^n ( m , n positive ganze Zahlen), jede Dezimalzahl als m/(2^n*5^n) . Da den Binärdateien die Primzahl fehlt factor 5 können alle Binärzahlen exakt durch Dezimalzahlen dargestellt werden, aber nicht umgekehrt.

0.3 = 3/(2^1 * 5^1) = 0.3

0.3 = [0.25/0.5] [0.25/0.375] [0.25/3.125] [0.2825/3.125]

          1/4         1/8         1/16          1/32

Sie erhalten also eine Zahl, die entweder höher oder niedriger als die angegebene Dezimalzahl ist. Immer.

Warum ist das wichtig? Rundung.

Normale Rundung bedeutet 0..4 nach unten, 5..9 nach oben. Es ist also tut egal, ob das Ergebnis entweder 0.049999999999 .... oder 0.0500000000 ... Sie wissen vielleicht, dass es 5 Cent bedeutet, aber der Computer weiß das nicht und rundet 0.4999 ... nach unten (falsch) und 0.5000 ... oben (rechts).

Da das Ergebnis von Fließkommaberechnungen immer kleine Fehlerterme enthält, ist die Entscheidung reines Glück. Hoffnungslos wird es, wenn man mit Binärzahlen dezimal auf- und abrunden will.

Nicht überzeugt? Sie bestehen darauf, dass in Ihrem Kontensystem alles in Ordnung ist? Aktiva und Passiva sind gleich? Ok, dann nehmen Sie jede der angegebenen formatierten Zahlen eines jeden Eintrags, analysieren Sie sie und summieren Sie sie mit einem unabhängigen Dezimalsystem!

Vergleichen Sie dies mit der formatierten Summe. Ups, da stimmt doch etwas nicht, oder?

Für diese Berechnung war extreme Genauigkeit und Treue erforderlich (wir verwendeten Oracle's FLOAT), damit wir die "Milliardstel eines Pennys", die anfallen, aufzeichnen konnten.

Es hilft nicht gegen diesen Irrtum. Denn alle Menschen gehen automatisch davon aus, dass der Computer richtig rechnet, und praktisch niemand prüft unabhängig.

0 Stimmen

Achten Sie aber darauf, dass Sie mindestens 4 Dezimalstellen im Dezimalfeld verwenden, wenn Sie Berechnungen damit durchführen wollen, insbesondere bei der Division.

1 Stimmen

Und stellen Sie sicher, dass Sie wissen, dass (standardmäßig) $0,045 auf $0,04 und $0,055 auf $0,06 aufrunden.

8 Stimmen

Für diejenigen, die sich nicht sicher sind, was Keith meint: Dezimaltypen verwenden eine andere Art der Rundung. Sie scheint allgemein als "Banker-Rundung" bezeichnet zu werden, aber Wikipedia hat eine Reihe von alternativen Bezeichnungen: Halbe bis gerade Rundung, unbiased rounding, convergent rounding, statistician's rounding, Dutch rounding, Gaussian rounding, or bankers' rounding ( de.wikipedia.org/wiki/ ).

47voto

Nakilon Punkte 33536

3 Stimmen

Das hat mich zum Lachen gebracht. Gut gemacht, Best Buy.

19 Stimmen

Ein Jahr lang bekam ich von einer Telefongesellschaft jeden Monat eine Rechnung über $0,01. Also habe ich online 0,02 Dollar bezahlt, dann bekam ich sechs Monate lang eine Rechnung über 0,01 Dollar, dann hörte es auf.

0 Stimmen

Nun, es wird eine Menge Wartungsarbeiten geben, um dieses Chaos zu beseitigen.

23voto

Rich Schuler Punkte 41316

Zuerst sollten Sie lesen Was jeder Informatiker über Fließkommaarithmetik wissen sollte . Dann sollten Sie wirklich erwägen, eine Art von Festkomma-/Beliebig-Präzisionszahl Paket (z. B. Java BigNum oder Python decimal module). Andernfalls droht Ihnen großes Ungemach. Finden Sie dann heraus, ob die Verwendung des nativen SQL-Dezimaltyps ausreicht.

Floats und Doubles existieren, um die schnelle x87-Gleitkomma-Coprozessor die jetzt so gut wie überholt ist. Verwenden Sie sie nicht, wenn Ihnen die Genauigkeit der Berechnungen wichtig ist und/oder Sie ihre Einschränkungen nicht vollständig ausgleichen können.

2 Stimmen

Während das Lernen mehr über Fließkomma ist nützlich, mit dem Dezimaltyp in C # ist ähnlich wie die Verwendung eines Festkomma / arbiträr-Präzision Zahlenpaket, wie Sie vorschlagen, in die Sprache eingebaut. Siehe msdn.microsoft.com/de-us/library/system.decimal.aspx für eine Erklärung, wie decimal genaue Potenzen von 10 mit Dezimalzahlen anstelle von Potenzen von 2 für die dezimale Komponente speichert (es ist im Grunde ein int mit einer dezimalen Platzierungskomponente).

2 Stimmen

"um die schnelle x87 fp freizulegen, die jetzt ziemlich veraltet ist", das ist einfach nicht wahr Fließkommazahlen sind immer noch einer der am häufigsten verwendeten Datentypen auf Computern, z.B. Simulationen, Spiele, Signalverarbeitung...

10voto

Darrel Miller Punkte 133891

Nur als zusätzliche Warnung: SQL Server und das .NET Framework verwenden einen anderen Standardalgorithmus für die Rundung. Stellen Sie sicher, dass Sie den Parameter MidPointRounding in Math.Round() überprüfen. Das .NET-Framework verwendet Bankenrundung und SQL Server verwendet standardmäßig die symmetrische algorithmische Rundung. Lesen Sie den Wikipedia-Artikel aquí .

0 Stimmen

Welchen Namen hat "Symmetric Algorithmic Rounding" in dem Wikipedia-Artikel? Oder ist es dort nicht aufgeführt? Welche es "Symmetrische algorithmische Rundung"? Können Sie eine Referenz hinzufügen?

7voto

Fragen Sie Ihre Buchhalter! Sie werden die Stirn runzeln, wenn Sie Float verwenden. Wie David Singer sagte verwenden Sie float nur wenn Ihnen die Genauigkeit egal ist. Obwohl ich immer dagegen sein würde, wenn es um Geld geht.

In der Buchhaltungssoftware ist no einen Schwebekörper akzeptieren. Verwenden Sie Dezimalzahlen mit vier Dezimalstellen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X