浮動小数点と10進数を使用する場合


14

このAPIを構築しています。データベースには、次のいずれかを表す値が格納されます。

  • 割合
  • 平均
  • 割合

正直に言って、範囲が0〜100%の数値を表現する方法がわかりません。それは

  • 0.00-1.00
  • 0.00-100.00
  • 私が知らない他の選択肢

そのための明確な選択肢はありますか?データベースで0から100%パーセントまでの何かを表すグローバルな方法は?さらに進んで、その正しいタイプは何ですか、浮動小数点または10進数ですか?

ありがとうございました。



5
数値はさまざまな方法で保存できます。0〜100を使用してパーセンテージを保存するか、0〜1を使用しても、本質的に問題はありません。重要なのは、数値をどのように処理する必要があるか、必要な精度などです。良い答えを出す前に、より多くのコンテキストを説明する必要があります。少数の10進数で正確に表現できる数値を格納する必要がありますか?物事を平均すると、3分の1や7分の1などの端数が得られます。それらを正確に保存する必要がありますか?またはちょうど約?おおよそ?あなたは彼らをどうしますか?
Eric Postpischil

1
値が0.01のステップで0.00から100.00である場合、それは10001の異なる値です。100分の1またはパーミリアドまたはofの単位でint表すには単にを使用します。
chux-モニカを

@ chux-ReinstateMonica-はい、「スケーリングされた整数」は可能ですが不器用です。
リックジェームズ

@RickJamesたぶん。スケーリングされた整数を難しいと思ったことはありません。
chux-モニカを

回答:


4

私は反対のスタンスをとります。

FLOATパーセンテージ、平均などの概数を表すものです。値をアプリコードで表示するか、FORMAT()MySQL の関数を使用して表示するときに、フォーマットを行う必要があります。

テストしないでくださいfloat_value = 1.3。それが失敗する理由はたくさんあります。

DECIMAL金額に使用する必要があります。 DECIMAL値をドル/セント/ユーロなどに丸める必要がある場合、2番目の丸めを回避します。会計士はセントの端数が好きではありません。

MySQLの実装ではDECIMAL、65桁の有効数字が許可されています。FLOAT約7とDOUBLE約16 を示します。通常、センサーと科学計算には7で十分です。

「パーセンテージ」については、TINYINT UNSIGNED1バイトのストレージのみを消費し、あまり精度を必要としない場合に使用することがあります。時々使用しましたFLOAT(4バイト)。特にパーセンテージ用に調整されたデータ型はありません。(また、それDECIMAL(2,0)は値を保持できないため、100技術的には必要になることに注意してくださいDECIMAL(3,0)。)

またはFLOAT、0と1の間の値を保持するを使用したこともありますが、「パーセンテージ」を表示する前に、必ず100を掛ける必要があります。

もっと

「パーセンテージ、平均、レート」の3つすべてがフロートのようなにおいがするので、それが私の最初の選択です。

データ型を決定するための1つの基準...値のコピーはいくつ存在しますか?

パーセンテージの列を含む10億行のテーブルがある場合、TINYINT1バイト(合計1GB)がFLOAT必要ですが、4バイト(合計4GB )になると考えてください。OTOH、ほとんどのアプリケーションにはそれほど多くの行がないため、これは関係がない場合があります。

「一般的な」ルールとして、「正確な」値には、INTまたはの形式を使用する必要がありますDECIMAL。不正確なもの(科学計算、平方根、除算など)はFLOAT(またはDOUBLE)を使用する必要があります。

さらに、出力のフォーマットは通常、アプリケーションのフロントエンドに任されています。つまり、「平均」が「14.6666666 ...」と計算されても、表示は「14.7」のように表示されます。これは人間にとってよりフレンドリーです。その間、「15」または「14.667」が望ましい出力フォーマットであると後で決定するための基礎となる値があります。

範囲 "0.00-100.00"はFLOAT 、出力フォーマットを使用してまたはDECIMAL(5,2)(3バイト)を使用して、常に指定された精度が必要であると事前に決定できます


3

私は一般的にを使用しないことをお勧めしfloatます。浮動小数点数は、基数2の数値を表します。基数2に正確に格納できないため、演算または比較で一部の(正確な)数値が切り上げられます。これは驚くべき行動につながる可能性があります。

次の例を考えてみます

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 |
| --: |

数値のbase-2比較は1.3失敗します。これはトリッキーです。

これに対して、decimalは、範囲内の有限数を正確に表現します。上記の例でに変更floatするdecimal(2, 1)と、期待どおりの結果が得られます。


4
この答えはいくつかの点で間違っています。「比較すると、10進数の範囲は狭いですが、その範囲内の有限数の正確な表現を提供します」は誤りです。10進数は⅓を正確に表しません。「一部の(正確な、有限の)数値は切り上げられます」は正しくありません。数値は「切り上げ」ではありません。変換およびその他の操作は丸められる場合があります。デフォルトの丸めモードは、最も一般的には、丸めではなく、最近傍から偶数に丸められます。
Eric Postpischil

4
精度の問題は、「浮動小数点数」によるものではなく、単に数値表現によるものです。すべての有限数値表現は、精度に制限があります:浮動小数点、固定小数点、整数、有理数、小数、バイナリ、すべて。
Eric Postpischil

2
はぁ。何を修正しましたか?私のコメントは、10進数はその範囲内の数値の正確な表現を提供するため、答えは間違っていると述べていますが、実際には、anの正確な表現を提供しないため、そうではありません。変更は「正確」ではなく「正確」と表示されますが、2進浮動小数点数がasに対して正確ではなく、どちらも正確ではなく、どちらが正確であるかは、正確のしきい値と精度によって異なります。彼らは持っている。質問は、平均が表されることを示し、3つのものを平均すると、likeのような数値が得られます。
Eric Postpischil、

4
コメントでは、最も近い値への丸めが最も一般的に使用されていると述べていますが、答えはまだ切り上げです。答えは、比較は切り上げられる可能性があると述べていますが、比較は完全です。比較は常に、丸めなしで数学的に正しい結果を返します。(一部のプログラミング言語では、比較する前にオペランドを変換する場合がありますが、それらは別々の演算です。)
Eric Postpischil

1
1/3は、2進数または10進数で正確に表すことはできません。14.99ドルから20%の割引は、端数を四捨五入する必要があるため、セントは存在しません。
Rick James

0

floatとdecimalの違いは精度です。Decimalは、10進形式の精度内で任意の数値を100%正確に表すことができますが、Floatはすべての数値を正確に表すことができません。

財務関連の値などにはDecimalを使用し、グラフィック関連の値などにはfloatを使用します


0

正確な精度を維持するため、decimal(5,2)表示と同じ方法decimalで保存する場合に使用することをお勧めします。(https://dev.mysql.com/doc/refman/8.0/en/fixed-point-types.htmlを参照してください

浮動小数点値は概算であり、正確な値として格納されていないため、比較でそれらを正確なものとして処理しようとすると、問題が発生する可能性があります。また、プラットフォームまたは実装の依存関係の影響を受けます。

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

SQLステートメントで記述された浮動小数点値は、内部的に表現された値と同じでない場合があります。

DECIMALカラムの場合、MySQLは65桁の精度で演算を実行します。これにより、最も一般的な不正確な問題が解決されます。

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


0

Decimal: 金融アプリケーションの場合は、Decimalタイプを使用することをお勧めします。高精度で丸め誤差を回避しやすいためです。

Double: Double型は、金額の処理を除いて、おそらく最も一般的に実際の値に使用されるデータ型です。

Float: 処理能力への要求が非常に高いため、ほとんどの場合グラフィックライブラリで使用され、丸めエラーに耐えられる状況も使用されます。

リファレンス: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

小数はこの場合に想定されていることを正確に実行し、残りを切り捨てて、1/3の部分を失いました。

したがって、合計の場合は小数の方が適していますが、除算の場合は浮動小数点のほうが優れています。つまり、DECIMALを使用しても、いかなる方法でも「フェイルプルーフ演算」が行われることはありません。

これがお役に立てば幸いです。


0

tsql:Float、0.0は0として保存され、小数点以下の桁を定義する必要はありません。たとえば、Float(4,2)を記述する必要はありません。Decimal、0.0は0.0として保存され、decimal(4,2)のように定義するオプションがあります。0.00〜1.00をお勧めします。これを行うと、100を掛けずにそのパーセントの値を計算でき、レポートしてからデータ型を設定できますその列のパーセントは、MS Excelや他のプラットフォームビューのようにパーセント0.5 -> 50%です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.