SQL Serverの数値、浮動小数点、および10進数の違い


322

違いは何ですかnumericfloatそしてdecimalどのような状況で使用されるべきデータ型とは?

あらゆる種類の金融取引(給与分野など)の場合、どちらが望ましいのですか。それはなぜですか。


1
上記の10進数と数値のリンクをdocs.microsoft.com/en-us/sql/t-sql/data-types/…に更新する必要があります。上記のリンクは存在しません。
Nigel Ainscoe 2017年

1
通常、財務主体を扱う場合、浮動小数点数以外の整数型を操作し、値をドルではなくセントなどとして格納するのは興味深いことです。
ペドロ

回答:


494

10進数で提供される精度(最大38桁)が不十分な場合のみfloatまたはrealデータ型を使用します

  • 概数値データ型は、多くの数値に対して指定さた正確な値を格納しません。それらは値の非常に近い近似値を保存します。(Technet

  • WHERE句の検索条件、特に=および<>演算子で浮動列または実列を使用しないようにします(Technet

そのため、一般に、数値が収まる場合、10進数提供される精度は[10E38〜38桁]であり、Floatの小さい記憶域(およびおそらく速度)は重要ではなく、異常な動作やおおよその数値型の問題への対処は重要ではありません。受け入れ可能、通常はDecimalを使用します

より役立つ情報

  • 数値= 10進数(5から17バイト)(正確な数値データ型)
    • .NETでDecimalにマップされます
    • どちらもSQLサーバーのデフォルト(精度、スケール)パラメーターとして(18、0)を持っています
    • スケール=小数点の右側に格納できる小数点の最大桁数。
    • money(8バイト)とsmallmoney(4バイト)も正確であり、.NETのDecimalにマップされ、小数点が4つあることに注意してください(MSDN
    • 10進数と数値(Transact-SQL)-MSDN
  • 実数(4バイト)(近似 数値データ型)
  • float(8バイト)(概数値 データ型)
    • .NETでDoubleにマップされます
  • 使用されているプロセッサアーキテクチャの種類や数値の大きさに関係なく、すべての正確な数値型は常に同じ結果を生成します
  • floatデータ型に提供されるパラメーターは、浮動小数点数の仮数を格納するために使用されるビット数を定義します。
  • 概算数値データタイプは、通常、使用するストレージが少なく、速度が優れています(最大20倍)。また、.NETで変換された時期も考慮する必要があります。

正確な数値データ型 近似数値データ型

主な出典MCTS Self-Paced Training Kit(Exam 70-433):Microsoft®SQLServer®2008 Database Development -Chapter 3-Tables、Data Types、and Declarative Data Integrity Lesson 1-Choosing Data Type(Guidelines)-Page 93


17
use the float or real data types only if the precision provided by decimal is insufficient-私は実数の方が10進数よりも少ないので正確だと思いました。
BornToCode

7
本当の精度に大きな数字、小数点(> 10e38)必要とされているか、スペースの考慮事項は引用手段の可能な値で、ここでの精度を推測.Iという大きなと大きさをしませ保存しない限り、推奨されませんので、それほど正確である
イマン

12
@BornToCodeここでの「精度」とは、格納する値の範囲の広さを指します。1e10と1e-10の間の値を格納する必要がある場合は、問題ありませんdecimal。これは精度は20です。たとえば、1e20と1e-20の間の値を格納する必要がある場合、それdecimal はできません。これは40桁の精度です。1e20と1e-20を同じdecimalフィールドに格納することはできません。代わりに、floatすべてを底2の対数として内部的に保存するを使用できます。これにより、1つのフィールドで全範囲の精度が可能になり、最初の〜8桁のみが正確になるという欠点があります。
ベーコンビット

BornToCodeとImanのコメントの3番目です。(SQL Server 2012を使用して)実験したところ、float(53)(最高精度の浮動小数点型)のマシンイプシロンは2.22044604925031E-16のようです。だからあなたはそれから約15の重要な数字を得るでしょう。一方、小数のうち38桁の有効数字を得ることができます。
スチュワート

「を使用してfloat...」-だれが言ったか。それは引用ですか、それともあなたの意見ですか?
user443854

24

MSDNのガイドライン:10進数、浮動小数点、および実際のデータの使用

numericおよびdecimalデータ型のデフォルトの最大精度は38です。Transact-SQLでは、numericは機能的にdecimalデータ型と同等です。データ値を指定どおりに格納する必要がある場合は、10進数データ型を使用して、10進数の数値を格納します。

floatおよびrealの動作は、概数値データ型に関するIEEE 754仕様に従います。floatおよびrealデータ型のおおよその性質のため、金融アプリケーション、丸めを含む操作、または等式チェックなどで正確な数値動作が必要な場合は、これらのデータ型を使用しないでください。代わりに、integer、decimal、money、またはsmallmoneyデータ型を使用してください。WHERE句の検索条件、特に=および<>演算子では、floatまたはreal列を使用しないでください。floatとrealの列を>または<の比較に制限するのが最善です。


(固定)小数点以下の桁数がScale列に指定されています。
Cees Timmerman、2014

1
あなたは基準が観点から、その後、「まさにとして指定した」したい場合は、いくつかの利点があるnumeric参照してください。あなたが尋ねたよりも、それをより正確に保存することはありませんので、stackoverflow.com/a/759606/626804
エドエイビス

13

完全な答えではありませんが、便利なリンク:

「私は10進値に対して頻繁に計算を行っています。場合によっては、計算の前に10進値をできるだけ早く浮動小数点にキャストすると、精度が向上します。」

http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/12/20/for-better-precision-cast-decimals-before-calculations.aspx


2
それは意味がありません。出典を含む他のすべての答えは、数値または10進数のデータ型は正確であり、浮動小数点または実数の型は非常に近い近似であると述べています。精度が低いため、float型にキャストすると、計算は速くなりますが、精度は高くならない可能性があることを理解できます。
cbaldan

3
すべての数値データ型でオーバーフローとアンダーフローが発生する可能性があります。オーバーフローは明示的なエラーですが、アンダーフローは発生しません。以下のためのアンダーフローの特性decimalfloatしている異なります。Decimalは、精度またはスケールを増やすことにより、アンダーフローを可能な限り防ぎます。ただし、10進数の有効桁数の制限に達すると、アンダーフローは発生しません(精度が失われます)。Floatは可能なスケールの範囲が広く、実際にアンダーフローの原因となっているのはスケールの制限です。したがって、floatはより適切なスケールを持つことができます。それにもかかわらず、それはまだ不正確なタイプです。
ErikE

13

データ型の優先順位が異なります

DecimalNumeric機能的には同じですが、データ型の優先順位が残っているため、場合によっては重要になることがあります。

SELECT SQL_VARIANT_PROPERTY(CAST(1 AS NUMERIC) + CAST(1 AS DECIMAL),'basetype')

結果のデータ型は、データ型が優先されるため、数値になります。

優先順位によるデータ型の完全なリスト:

参照リンク


7

小数は固定精度で、浮動小数点は可変精度です。

編集(質問全体を読み取れませんでした):Float(53)(別名は実数)は、SQL Serverの倍精度(32ビット)浮動小数点数です。通常の浮動小数点は、単精度の浮動小数点数です。Doubleは、多くの計算において、精度と単純さの優れた組み合わせです。10進数で非常に高い精度の数値(最大136ビット)を作成できますが、必要な桁数までのすべての中間計算を含めることができるように、精度を正確に定義して正しくスケールすることにも注意する必要があります。


あなたは、ケースが金融取引のために行く間、どちらが好ましいか特定しませんでした、そして、なぜですか?
priyanka.sarkar 2009年

SQL Server 2008以降の場合、float(53)別名floatは倍精度(64ビット)浮動小数点数ですが、float(24)別名実数は単精度(32ビット)浮動小数点数です。docs.microsoft.com/en-us/sql/t-sql/data-types/float-and-real-transact-sql
M Kloster

4

Floatは概数データ型です。つまり、データ型の範囲内のすべての値を正確に表現できるわけではありません。

Decimal / NumericはFixed-Precisionデータタイプです。つまり、データタイプの範囲内のすべての値を、精度と位取りで正確に表すことができます。お金を節約するために小数を使用できます。

DecimalまたはNumericからfloatに変換すると、精度がいくらか失われる可能性があります。DecimalまたはNumericデータ型の場合、SQL Serverは精度と位取りの特定の組み合わせをそれぞれ異なるデータ型と見なします。DECIMAL(2,2)とDECIMAL(2,4)は異なるデータ型です。これは、フロートの場合はそうではありませんが、11.22と11.2222は異なるタイプであることを意味します。FLOAT(6)の場合、11.22と11.2222は同じデータ型です。

お金を節約するためにmoneyデータ型を使用することもできます。これは、お金のために4桁の精度を持つネイティブデータ型です。ほとんどの専門家は、お金を節約するためにこのデータ型を好みます。

リファレンス 1 2 3


3

10進数の場合

根本的なニーズは何ですか?

これは、最終的に、コンピュータが内部的に数値をバイナリ形式で表すという事実から生じます。これは必然的に丸め誤差につながります。

このことを考慮:

0.1 (decimal, or "base 10") = .00011001100110011... (binary, or "base 2")

上記の省略記号[...]は「無限」を意味します。注意深く見ると、無限の繰り返しパターンがあります(= '0011')

したがって、ある時点でコンピュータはその値を丸める必要があります。これは、不正確に格納された数値の繰り返し使用から生じる累積エラーにつながります。

財務量(小数部を含む可能性のある数値)を保存するとします。まず、明らかに整数を使用することはできません(整数には小数部はありません)。純粋に数学的な観点から見ると、自然な傾向はを使用することfloatです。しかし、コンピューターでは、浮動小数点数は、小数点の後にある数値の一部(「仮数」)を持っています。これにより、丸め誤差が発生します。

これを克服するために、コンピューターは、10進数のコンピューターのバイナリ丸め誤差を制限する特定のデータ型を提供します。これらは、金額を表すために絶対に使用する必要があるデータ型です。これらのデータ型は、通常、の名前になりDecimalます。たとえば、C#の場合です。または、DECIMALほとんどのデータベースで。


1

質問にはMONEYデータ型は含まれていませんが、このスレッドに出くわす人々の中には、財務計算にMONEYデータ型を使用したくなるかもしれません。

MONEYデータ型には注意してください。精度に制限があります。

このStackoverflowの質問への回答には、それに関する多くの優れた情報があります。

SQL ServerでMONEYまたはDECIMAL(x、y)データ型を選択する必要がありますか?

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