Wann wird float vs decimal verwendet?


14

Ich erstelle diese API und die Datenbank speichert Werte, die einen der folgenden Werte darstellen:

  • Prozentsatz
  • durchschnittlich
  • Bewertung

Ich habe ehrlich gesagt keine Ahnung, wie ich etwas darstellen soll, dessen Zahlen zwischen 0 und 100% liegen. Sollte es sein

  • 0,00 - 1,00
  • 0,00 - 100,00
  • jede andere Alternative, die ich nicht kenne

Gibt es dafür eine klare Wahl? Eine globale Art, in Datenbanken etwas darzustellen, das von 0 bis 100% Prozent reicht? Was ist der richtige Typ dafür, float oder decimal?

Vielen Dank.



5
Zahlen können auf viele Arten gespeichert werden. Es ist an sich nichts Falsches daran, einen Prozentsatz mit 0-100 oder mit 0-1 zu speichern. Was zählt, ist, was Sie mit den Zahlen tun müssen, welche Genauigkeit Sie benötigen und so weiter. Sie müssen mehr Kontext erklären, bevor eine gute Antwort gegeben werden kann. Müssen Sie Zahlen speichern, die mit einer kleinen Anzahl von Dezimalstellen genau darstellbar sind? Wenn Sie Dinge durchschnittlich machen, erhalten Sie Brüche wie Drittel oder Siebtel. Müssen Sie diese genau speichern? Oder nur ungefähr? Wie ungefähr? Was wirst du mit ihnen machen?
Eric Postpischil

1
Wenn die Werte in Schritten von 0,01 zwischen 0,00 und 100,00 liegen, sind dies 10001 verschiedene Werte. Verwenden Sie einfach ein int, um Hundertstel oder in Einheiten von Permyriad oder ‱ darzustellen.
chux - Monica

@ chux-ReinstateMonica - Ja, "skalierte Ganzzahlen" sind möglich, aber ungeschickt.
Rick James

@ RickJames Vielleicht. Ich habe skalierte Ganzzahlen nicht als schwierig empfunden.
chux - Monica

Antworten:


4

Ich werde die entgegengesetzte Haltung einnehmen.

FLOATDies gilt für ungefähre Zahlen wie Prozentsätze, Durchschnittswerte usw. Sie sollten die Formatierung durchführen, während Sie die Werte entweder im App-Code oder mithilfe der FORMAT()Funktion von MySQL anzeigen .

Testen Sie niemals float_value = 1.3; Es gibt viele Gründe, warum dies fehlschlagen wird.

DECIMALsollte für Geldwerte verwendet werden. DECIMALvermeidet eine zweite Rundung, wenn ein Wert auf Dollar / Cent / Euro / etc. gerundet werden muss. Buchhalter mögen keine Bruchteile von Cent.

Die Implementierung von MySQL DECIMALerlaubt 65 signifikante Stellen. FLOATgibt ungefähr 7 und DOUBLEungefähr 16. 7 ist normalerweise mehr als genug für Sensoren und wissenschaftliche Berechnungen.

Wie für "Prozentsatz" - Manchmal habe ich verwendet, TINYINT UNSIGNEDwenn ich nur 1 Byte Speicher verbrauchen möchte und nicht viel Präzision benötige; manchmal habe ich verwendet FLOAT(4 Bytes). Es gibt keinen Datentyp, der speziell auf den Prozentsatz abgestimmt ist. (Beachten Sie auch, dass DECIMAL(2,0)der Wert nicht gespeichert werden kann 100, also technisch würden Sie ihn benötigen DECIMAL(3,0).)

Oder manchmal habe ich eine verwendet FLOAT, die einen Wert zwischen 0 und 1 hat. Dann müsste ich jedoch sicherstellen, dass sie mit 100 multipliziert wird, bevor der "Prozentsatz" angezeigt wird.

Mehr

Alle drei von "Prozentsatz, Durchschnitt, Rate" riechen nach Schwimmern, das wäre also meine erste Wahl.

Ein Kriterium für die Entscheidung über den Datentyp ... Wie viele Kopien des Werts werden vorhanden sein?

Wenn Sie eine Milliardenzeilentabelle mit einer Spalte für einen Prozentsatz haben, sollten Sie berücksichtigen, dass TINYINTdies 1 Byte (insgesamt 1 GB), aber FLOAT4 Byte (insgesamt 4 GB) dauern würde. OTOH, die meisten Anwendungen haben nicht so viele Zeilen, daher ist dies möglicherweise nicht relevant.

In der Regel sollten "exakte" Werte eine Form von INToder verwenden DECIMAL. Ungenaue Dinge (wissenschaftliche Berechnungen, Quadratwurzeln, Division usw.) sollten verwendet werden FLOAT(oder DOUBLE).

Darüber hinaus sollte die Formatierung der Ausgabe normalerweise dem Frontend der Anwendung überlassen bleiben. Das heißt, obwohl ein "Durchschnitt" zu "14.6666666 ..." berechnen kann, sollte die Anzeige so etwas wie "14.7" anzeigen; Das ist freundlicher für den Menschen. In der Zwischenzeit haben Sie den zugrunde liegenden Wert, um später zu entscheiden, dass "15" oder "14.667" die bevorzugte Ausgabeformatierung ist.

Der Bereich "0,00 - 100,00" kann entweder mit FLOAT und unter Verwendung der Ausgabeformatierung oder mit DECIMAL(5,2)(3 Bytes) mit der Voreinstellung festgelegt werden, dass Sie immer die angegebene Genauigkeit wünschen .


3

Ich würde generell davon abraten, es zu benutzen float. Gleitkommazahlen stellen Zahlen in Basis 2 dar, was dazu führt, dass einige (exakte) Zahlen in Operationen oder Vergleichen aufgerundet werden, da sie in Basis 2 einfach nicht genau gespeichert werden können. Dies kann zu überraschenden Verhaltensweisen führen.

Betrachten Sie das folgende Beispiel :

create table t (num float);
insert into t values(1.3);

select * from t;

| num |
| --: |
| 1.3 |

select * from t where num = 1.3;

| num |
| --: |

Der Basis-2-Vergleich der Anzahl 1.3schlägt fehl. Das ist schwierig.

Im Vergleich dazu liefern Dezimalstellen eine genaue Darstellung endlicher Zahlen innerhalb ihres Bereichs. Wenn Sie ändern , floatum decimal(2, 1)in dem obigen Beispiel, haben Sie die erwarteten Ergebnisse erzielen.


4
Diese Antwort ist in mehrfacher Hinsicht falsch. "Im Vergleich dazu haben Dezimalstellen einen kleineren Bereich, bieten aber eine genaue Darstellung endlicher Zahlen innerhalb dieses Bereichs" ist falsch: Dezimalstellen stehen nicht genau für ⅓. "Einige (genaue, endliche) Zahlen sind aufgerundet" ist falsch; Zahlen sind keine "Aufrundung". Konvertierungen und andere Vorgänge können gerundet sein. Der Standardrundungsmodus ist meistens Rundung auf die nächste Gleichheit, nicht Aufrundung.
Eric Postpischil

4
Probleme mit der Genauigkeit sind nicht auf „Gleitkommazahlen“ zurückzuführen, sondern lediglich auf numerische Darstellungen: Alle endlichen numerischen Darstellungen haben eine begrenzte Genauigkeit: Gleitkomma-, Festkomma-, Ganzzahl-, Rational-, Dezimal-, Binär- und alles.
Eric Postpischil

2
Seufzer. Was hast du behoben? Mein Kommentar besagt, dass die Antwort falsch ist, weil sie besagt, dass Dezimalstellen eine genaue Darstellung von Zahlen innerhalb ihres Bereichs liefern, aber tatsächlich nicht, weil sie keine genaue Darstellung von ⅓ liefern. Die Änderung lautet "genau" statt "genau", aber warum ist der binäre Gleitkomma dann nicht genauso gut - keiner ist genau für ⅓ und beide oder keiner sind genau, je nachdem, wie hoch Ihr Genauigkeitsschwellenwert ist und wie genau er ist Sie haben. Die Frage zeigt an, dass Durchschnittswerte dargestellt werden, und der Durchschnitt von drei Dingen ergibt Zahlen wie ⅓.
Eric Postpischil

4
Der Kommentar besagt, dass Round-to-Next-Tie-to-Even am häufigsten verwendet wird, aber die Antwort lautet immer noch Round-up. Die Antwort besagt, dass Vergleiche zwar aufrunden können, aber Vergleiche perfekt sind: Vergleiche liefern immer ein mathematisch korrektes Ergebnis ohne Rundung. (Einige Programmiersprachen konvertieren möglicherweise Operanden vor dem Vergleich, dies sind jedoch separate Operationen.)
Eric Postpischil

1
1/3 kann weder binär noch dezimal genau dargestellt werden. Ein Rabatt von 20% auf 14,99 USD erfordert, dass keine Rundungsbruchteile vorhanden sind.
Rick James

0

Der Unterschied zwischen Gleitkomma- und Dezimalzahl ist die Genauigkeit. Dezimal kann 100% genau innerhalb der Genauigkeit des Dezimalformats darstellen, während Float nicht alle Zahlen genau darstellen kann.

Verwenden Sie Dezimal für z. B. den finanziellen Wert und float für z. B. den grafischen Wert


0

Ich empfehle die Verwendung, decimal(5,2)wenn Sie es auf die gleiche Weise speichern möchten, wie Sie es anzeigen, da decimaldie genaue Genauigkeit erhalten bleibt. (Siehe https://dev.mysql.com/doc/refman/8.0/en/fixed-point-types.html )

Da Gleitkommawerte ungefähre Werte sind und nicht als exakte Werte gespeichert werden, können Versuche, sie in Vergleichen als exakt zu behandeln, zu Problemen führen. Sie unterliegen auch Plattform- oder Implementierungsabhängigkeiten.

( https://dev.mysql.com/doc/refman/8.0/en/floating-point-types.html )

Ein Gleitkommawert, wie er in einer SQL-Anweisung geschrieben ist, stimmt möglicherweise nicht mit dem intern dargestellten Wert überein.

Für DECIMAL-Spalten führt MySQL Operationen mit einer Genauigkeit von 65 Dezimalstellen aus, wodurch die häufigsten Ungenauigkeitsprobleme gelöst werden sollten.

https://dev.mysql.com/doc/refman/8.0/en/problems-with-float.html


0

Dezimal: Bei Finanzanwendungen ist es besser, Dezimaltypen zu verwenden, da dies ein hohes Maß an Genauigkeit bietet und Rundungsfehler leicht zu vermeiden sind

Double: Double Types sind wahrscheinlich der am häufigsten verwendete Datentyp für reale Werte, außer für den Umgang mit Geld.

Float: Es wird hauptsächlich in Grafikbibliotheken verwendet, da sehr hohe Anforderungen an die Verarbeitungsleistung gestellt werden und auch Situationen verwendet werden, in denen Rundungsfehler auftreten können.

Referenz: http://net-informations.com/q/faq/float.html


0
mysql> create table numbers (a decimal(10,2), b float);
mysql> insert into numbers values (100, 100);
mysql> select @a := (a/3), @b := (b/3), @a * 3, @b * 3 from numbers \G

*********************************************************************

@a := (a/3): 33.333333333
@b := (b/3): 33.333333333333
@a + @a + @a: 99.999999999000000000000000000000
@b + @b + @b: 100

Die Dezimalstelle hat genau das getan, was in diesen Fällen zu tun ist. Sie hat den Rest abgeschnitten und damit den 1/3 Teil verloren.

Für Summen ist die Dezimalzahl also besser, aber für Divisionen ist der Float besser, natürlich bis zu einem gewissen Punkt. Ich meine, mit DECIMAL erhalten Sie in keiner Weise eine "ausfallsichere Arithmetik".

Ich hoffe das wird helfen.


0

In tsql: Float wird 0.0 als 0 gespeichert und muss nicht nach der Dezimalstelle definiert werden, z. B. muss Float (4,2) nicht geschrieben werden. Dezimal, 0.0 als 0.0 speichern und es hat die Option, wie Dezimal (4,2) zu definieren. Ich würde 0,00-1,00 vorschlagen. Auf diese Weise können Sie den Wert dieses Prozentsatzes berechnen, ohne mit 100 zu multiplizieren. Wenn Sie einen Bericht erstellen, legen Sie den Datentyp fest dieser Spalte in Prozent wie MS Excel und andere Plattformansichten wie 0.5 -> 50%.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.