違いは何ですかdecimal
、float
とdouble
.NETのは?
いつこれらのいずれかを使用しますか?
違いは何ですかdecimal
、float
とdouble
.NETのは?
いつこれらのいずれかを使用しますか?
回答:
float
そして、double
されている浮動進小数点型を。つまり、次のような数値を表します。
10001.10010110011
2進数と2進小数点の位置の両方が値内にエンコードされます。
decimal
は浮動小数点タイプです。つまり、次のような数値を表します。
12345.65789
繰り返しになりますが、小数点の数と位置はどちらも値内にエンコードされますdecimal
。これが、固定小数点型ではなく浮動小数点型になる理由です。
注意すべき重要なことは、人間は非整数を10進形式で表現することに慣れており、正確な結果を10進表現で期待することです。すべての10進数が2進浮動小数点(たとえば、0.1)で正確に表現できるわけではないため、2進浮動小数点値を使用すると、実際には0.1に近い値が得られます。浮動小数点を使用した場合でも、近似値が得られます。たとえば、1を3で除算した結果は、正確に表すことができません。
何を使用するかについては:
「自然に正確な小数」である値には、を使用することをお勧めしますdecimal
。これは通常、人間が発明したすべての概念に適しています。金銭的価値は最も明白な例ですが、他にもあります。例えば、ダイバーやアイススケーターに与えられるスコアを考えてみてください。
とにかく正確に測定することができない自然のより多くのアーティファクトである値の場合、float
/ double
がより適切です。たとえば、科学データは通常、この形式で表されます。ここでは、元の値は最初は「10進数の精度」ではないため、期待される結果が「10進数の精度」を維持することは重要ではありません。浮動小数点型は、10進数よりもはるかに高速に処理できます。
float
/ double
通常はとして数値を表しません101.101110
。通常、次のように表されます1101010 * 2^(01010010)
-指数
float
、C#のエイリアスキーワードであり、.Netタイプではないことに驚いています。それはSystem.Single
..でsingle
ありdouble
、浮動小数点型です。
精度が主な違いです。
フロート -7桁(32ビット)
2桁の-15-16桁(64ビット)
10進数の -28-29の有効数字(128ビット)
小数の精度ははるかに高く、通常、高い精度を必要とする金融アプリケーションで使用されます。10進数はdouble / floatよりもはるかに低速です(一部のテストでは最大20倍)。
小数とフロート/ダブルはキャストなしでは比較できませんが、フロートとダブルは比較できます。10進数では、エンコードまたは末尾のゼロも使用できます。
float flt = 1F/3;
double dbl = 1D/3;
decimal dcm = 1M/3;
Console.WriteLine("float: {0} double: {1} decimal: {2}", flt, dbl, dcm);
結果:
float: 0.3333333
double: 0.333333333333333
decimal: 0.3333333333333333333333333333
0.1
-それは現実の世界ではめったにありません! 任意の有限の記憶形式は、ビットパターンの有限数に可能な値の無限の数をconflateう。たとえば、float
はとを融合0.1
し0.1 + 1e-8
、decimal
はとを融合0.1
し0.1 + 1e-29
ます。確かに、所定の範囲内で、特定の値(例えば精度のゼロ損失で任意の形式で表現することができfloat
、精度のゼロ損失で1.6e7に任意の整数を格納することができる) -それはまだない無限の精度。
0.1
はありません!人間がベース10 を好むため、0.1
「より良い」唯一のことです。値があっても、2つの値を同じ方法で初期化すると、どちらも同じ値になります。それはその値が正確ではないということだけです -それはそれに最も近い値となり、として正確に表すことができます。確かに、2進浮動小数点数では、10進浮動小数点数でもです。 どちらも完全に正確ではありません。0.10000001
float
0.1
0.1
0.1
float
(1.0 / 10) * 10 != 1.0
(1.0 / 3) * 3 != 1.0
double a = 0.1; double b = 0.1;
、その後a == b
trueになります。それはそれだけでa
あり、両方が正確に等しくb
なることはありません0.1
。C#では、あなたがしなければdecimal a = 1.0m / 3.0m; decimal b = 1.0m / 3.0m;
、その後a == b
もtrueになります。しかし、その場合には、どちらのa
もb
う正確に等しい1/3
-彼らは両方とも等しくなります0.3333...
。では、両方の場合、いくつかの精度は表現のために失われます。あなたは頑固にdecimal
、それがfalseである「無限」の精度を持っていると言います。
Decimal構造は、精度を必要とする財務計算に厳密に合わせられており、丸めには比較的耐性があります。ただし、いくつかの理由により、小数は科学的アプリケーションには適していません。
+---------+----------------+---------+----------+---------------------------------------------+
| C# | .Net Framework | Signed? | Bytes | Possible Values |
| Type | (System) type | | Occupied | |
+---------+----------------+---------+----------+---------------------------------------------+
| sbyte | System.Sbyte | Yes | 1 | -128 to 127 |
| short | System.Int16 | Yes | 2 | -32768 to 32767 |
| int | System.Int32 | Yes | 4 | -2147483648 to 2147483647 |
| long | System.Int64 | Yes | 8 | -9223372036854775808 to 9223372036854775807 |
| byte | System.Byte | No | 1 | 0 to 255 |
| ushort | System.Uint16 | No | 2 | 0 to 65535 |
| uint | System.UInt32 | No | 4 | 0 to 4294967295 |
| ulong | System.Uint64 | No | 8 | 0 to 18446744073709551615 |
| float | System.Single | Yes | 4 | Approximately ±1.5 x 10-45 to ±3.4 x 1038 |
| | | | | with 7 significant figures |
| double | System.Double | Yes | 8 | Approximately ±5.0 x 10-324 to ±1.7 x 10308 |
| | | | | with 15 or 16 significant figures |
| decimal | System.Decimal | Yes | 12 | Approximately ±1.0 x 10-28 to ±7.9 x 1028 |
| | | | | with 28 or 29 significant figures |
| char | System.Char | N/A | 2 | Any Unicode character (16 bit) |
| bool | System.Boolean | N/A | 1 / 2 | true or false |
+---------+----------------+---------+----------+---------------------------------------------+
他の回答やコメントで既に回答されているたくさんの良い(そしていくつかの悪い)情報を繰り返すことはしませんが、私はあなたのフォローアップの質問にヒントで答えます:
いつこれらのいずれかを使用しますか?
カウント値に小数を使用
測定値にはfloat / doubleを使用します
いくつかの例:
お金(お金を数えるか、お金を測定するか?)
距離(距離をカウントするか、距離を測定するか?*)
スコア(スコアをカウントするか、スコアを測定するか?)
私たちは常にお金を数え、決してそれを測定すべきではありません。通常、距離を測定します。私たちはしばしばスコアを数えます。
*場合によっては、「公称距離」と呼ばれることもありますが、実際に距離を「カウント」したい場合があります。たとえば、都市までの距離を示す国の標識を扱っていて、それらの距離には10進数字(xxx.x km)が2桁以上ないことがわかっています。
float
7桁の精度
double
約15桁の精度
decimal
約28桁の精度
精度を上げる必要がある場合は、floatではなくdoubleを使用してください。最近のCPUでは、両方のデータタイプのパフォーマンスがほぼ同じです。フロートを使用する唯一の利点は、場所を取らないことです。あなたがそれらをたくさん持っている場合にのみ、実質的に重要です。
これは面白いと思いました。すべてのコンピューター科学者が浮動小数点演算について知っておくべきこと
double
32ビットを超える整数型が利用できdouble
ず、53ビット整数型であるかのように使用されていた(たとえば、整数のペニー、または100分の1セントの整数)。最近ではそのようなことはあまり使われていませんが、多くの言語では、64ビット(場合によっては32ビットの場合もある)整数演算が行われるずっと前に倍精度浮動小数点値を使用できるようになりました。
Real
が-32768〜+32767に制限されていましたが、IIRCが単位精度で1.8E + 19までの値を表すことができるTurbo-87でした。会計アプリケーションReal
がペニーの整数を表すために使用するのは、より賢明だと思います...
double
、9E15までの単位精度を持つ型を持つことは非常に一般的でした。利用可能な最大の整数型よりも大きい整数を格納する必要がある場合double
、特にプロセッサが16x16-> 32またはそれ以上を実行する命令を持っている場合、を使用することは、多倍精度計算を試そうとするよりも簡単で効率的です。 ..
誰もそれについて言及していません
デフォルト設定では、Floats(System.Single)とdoubles(System.Double)はオーバーフローチェックを使用しませんが、Decimal(System.Decimal)は常にオーバーフローチェックを使用します。
というのは
decimal myNumber = decimal.MaxValue;
myNumber += 1;
OverflowExceptionをスローします。
しかし、これらはしません:
float myNumber = float.MaxValue;
myNumber += 1;
&
double myNumber = double.MaxValue;
myNumber += 1;
float.MaxValue+1 == float.MaxValue
と同じようにdecimal.MaxValue+0.1D == decimal.MaxValue
。たぶん、あなたは何かのような意味float.MaxValue*2
ですか?
System.Decimal
全体のユニットを区別することができなくなる直前に、例外がスローされますが、アプリケーションは、例えばドルとセントを扱うことになっている場合、それは遅すぎるかもしれません。
decimal
をゼロ(CS0020)で除算しようとした場合にのみ失敗し、整数リテラルについても同様です。ただし、実行時の10進数値をゼロで割ると、コンパイルエラーではなく例外が発生します。
前述のように、整数は整数です。.7、.42、.007などのポイントは保存できません。整数ではない数値を格納する必要がある場合は、別のタイプの変数が必要です。ダブルタイプまたはフロートタイプを使用できます。これらのタイプの変数は、まったく同じ方法int
で設定します。単語を使用する代わりに、double
またはを入力しますfloat
。このような:
float myFloat;
double myDouble;
(float
は「浮動小数点」の略で、端に何か点がある数字を意味します。)
2つの違いは、保持できる数値のサイズです。の場合float
、番号には7桁まで使用できます。以下のためdouble
の、あなたは16桁まで持つことができます。より正確には、公式サイズは次のとおりです。
float: 1.5 × 10^-45 to 3.4 × 10^38
double: 5.0 × 10^-324 to 1.7 × 10^308
float
は32ビットの数値でdouble
、64ビットの数値です。
新しいボタンをダブルクリックして、コードを取得します。次の3行をボタンコードに追加します。
double myDouble;
myDouble = 0.007;
MessageBox.Show(myDouble.ToString());
プログラムを停止して、コーディングウィンドウに戻ります。この行を変更します。
myDouble = 0.007;
myDouble = 12345678.1234567;
プログラムを実行し、ダブルボタンをクリックします。メッセージボックスに番号が正しく表示されます。ただし、最後に別の数値を追加すると、C#は再度切り上げまたは切り捨てを行います。道徳は、正確さが必要な場合は、丸めに注意してください!
decimal
実際には10進数形式で格納されます(基数2ではなく、2つの数値システム間の変換により数字が失われたり丸められたりすることはありません)。さらに、decimal
NaN、-0、∞、-∞などの特別な値の概念はありません。
これは私にとって興味深いスレッドでした。今日、decimal
精度がに劣るという点で、厄介な小さなバグが発生しましたfloat
。
C#コードでは、Excelスプレッドシートから数値を読み取り、それらをに変換してから、decimal
これdecimal
をサービスに送信してSQL Serverデータベースに保存しています。
Microsoft.Office.Interop.Excel.Range cell = …
object cellValue = cell.Value2;
if (cellValue != null)
{
decimal value = 0;
Decimal.TryParse(cellValue.ToString(), out value);
}
これで、ほとんどすべてのExcel値で、これは美しく機能しました。しかし、一部の非常に小さなExcel値でdecimal.TryParse
は、値を完全に使用できなくなりました。そのような例の1つは
cellValue = 0.00006317592
Decimal.TryParse(cellValue.ToString()、out value); // 0を返します
奇妙なことに、解決策はExcelの値をdouble
最初に変換し、次にに変換することでしたdecimal
:
Microsoft.Office.Interop.Excel.Range cell = …
object cellValue = cell.Value2;
if (cellValue != null)
{
double valueDouble = 0;
double.TryParse(cellValue.ToString(), out valueDouble);
decimal value = (decimal) valueDouble;
…
}
double
精度はaよりも低くなりますがdecimal
、これにより実際には小さな数字も認識されることが保証されます。何らかの理由で、double.TryParse
実際にはそのような小さな数を取得できましたが、decimal.TryParse
それらをゼロに設定していました。
奇数。非常に奇妙な。
decimal.Parse("0.00006317592")
動作します-何か他のことが起こっています。-おそらく科学的表記ですか?
メモリとパフォーマンスの両方が重要であるゲームや組み込みシステムなどのアプリケーションの場合、floatは、doubleの半分のサイズで高速であるため、通常、数値タイプの選択肢です。以前は整数が選択の武器でしたが、最新のプロセッサでは浮動小数点のパフォーマンスが整数を上回っています。10進数はすぐです。
Decimal、Double、およびFloat変数タイプは、値を格納する方法が異なります。精度は、floatが単精度(32ビット)浮動小数点データ型、doubleが倍精度(64ビット)浮動小数点データ型、10進数が128ビット浮動小数点データ型の場合の主な違いです。
フロート-32ビット(7桁)
ダブル-64ビット(15-16桁)
10進数-128ビット(有効数字28〜29桁)
詳細... Decimal、Float、Doubleの違い
これらすべてのタイプの問題は、特定の不正確さが存在すること、およびこの問題が次の例のように小さい10進数で発生する可能性があることです。
Dim fMean as Double = 1.18
Dim fDelta as Double = 0.08
Dim fLimit as Double = 1.1
If fMean - fDelta < fLimit Then
bLower = True
Else
bLower = False
End If
質問:bLower変数にはどの値が含まれていますか?
回答:32ビットマシンでは、bLowerにはTRUEが含まれています!!!
DoubleをDecimalに置き換えると、bLowerにFALSEが含まれます。これが適切な答えです。
doubleでは、問題は、1.1よりも低いfMean-fDelta = 1.09999999999です。
注意:Decimalは倍精度が高く、精度が常に制限されているため、他の数値でも同じ問題が確実に存在する可能性があると思います。
実際、Double、Float、DecimalはCOBOLのBINARY decimalに対応しています!
COBOLで実装されている他の数値型が.Netに存在しないのは残念です。COBOLを知らない人のために、COBOLには以下の数値型が存在します
BINARY or COMP like float or double or decimal
PACKED-DECIMAL or COMP-3 (2 digit in 1 byte)
ZONED-DECIMAL (1 digit in 1 byte)
簡単な言葉で:
/==========================================================================================
Type Bits Have up to Approximate Range
/==========================================================================================
float 32 7 digits -3.4 × 10 ^ (38) to +3.4 × 10 ^ (38)
double 64 15-16 digits ±5.0 × 10 ^ (-324) to ±1.7 × 10 ^ (308)
decimal 128 28-29 significant digits ±7.9 x 10 ^ (28) or (1 to 10 ^ (28)
/==========================================================================================
詳しくは、Float、Double、Decimalをご覧ください。
Decimal
、金融アプリケーションに適したものであり、との間Decimal
で決定するときに使用する主な基準Double
です。Double
たとえば、科学アプリケーションに精度が不十分であることはまれです(範囲が限られているため、科学アプリケーションにDecimal
は適さないことがよくあります)。
これらのそれぞれの主な違いは、精度です。
float
は32-bit
数値、double
は64-bit
数値、decimal
は128-bit
数値です。
Decimal 128ビット(有効数字28-29桁)金融アプリケーションの場合、高精度が得られ、丸めエラーを簡単に回避できるため、Decimal型を使用することをお勧めします。お金と通貨)
ダブル 64ビット(15〜16桁)ダブルタイプは、金額の処理を除いて、実際の値に最もよく使用されるデータタイプです。最も正確な答えが不要な非整数演算にはdoubleを使用します。
フロート 32ビット(7桁)処理能力に対する要求が非常に高いため、ほとんどの場合グラフィックライブラリで使用され、丸めエラーに耐えられる状況も使用されます。
Decimals
に比べてはるかに遅いですdouble/float
。
Decimals
そしてFloats/Doubles
一方、キャストせずに比較することはできませんFloats
とDoubles
することができます。
Decimals
また、エンコードまたは後続ゼロを許可します。