.net - 違い - 浮動小数点 誤差 対策 c言語




.NETの10進数、浮動小数点数、および倍数の違いは? (11)

.NETのdecimalfloat decimal 、およびdecimalの違いは何ですか?

いつ誰かがこれらのいずれかを使用しますか?


  1. doubleとfloatは、コンパイル時と実行時の両方で例外なく整数ゼロで除算できます。
  2. 小数は整数0で除算することはできません。 あなたがそれを行うと、コンパイルは常に失敗します。

7桁の精度をfloat

doubleは約15桁の精度があります

decimalの精度は約28桁です

より正確な精度が必要な場合は、floatの代わりにdoubleを使用します。 現代のCPUでは、両方のデータ型がほぼ同じ性能を持っています。 浮動小数点を使用する唯一の利点は、占有スペースが少なくて済むことです。 あなたがそれらの多くを持っている場合にのみ実際に重要です。

私はこれが興味深いとわかりました。 すべてのコンピュータ科学者が浮動小数点演算について知っておくべきこと


Decimal構造は、精度を必要とする財務計算に厳密に基づいており、丸めを比較的許容しません。 しかし、いくつかの理由から、小数点以下の桁数は科学的な用途には不十分です。

  • 物理的な問題やアーチファクトが実際に測定されるため、多くの科学的計算ではある程度の精度の低下が許容されます。 正確性の喪失は、金融では受け入れられません。
  • 浮動小数点演算はバイナリで行われるため、小数は基本10で行われます(つまり浮動小数点数と倍数はMMX / SSEなどのFPUハードウェアによって処理されます)。小数はソフトウェアで計算されます)。
  • Decimalは、より多くの精度の桁数をサポートしているにもかかわらず、doubleよりも容認できないほど小さな値の範囲を持ちます。 したがって、多くの科学的価値を表現するためにDecimalを使用することはできません。

floatdouble浮動小数点型です。 つまり、次のような数字を表します。

10001.10010110011

バイナリ番号とバイナリポイントの位置は、どちらも値内でエンコードされます。

decimal浮動小数点です。 つまり、次のような数字を表します。

12345.65789

繰り返しますが、 小数点の数と位置は両方とも値の中にコード化されています。つまり、小数点は固定小数点型の代わりに浮動小数点型になります。

重要なことは、人間は10進表現で非整数を表現することに慣れており、10進表現で正確な結果を期待することです。 たとえば、すべての10進数が2進浮動小数点 - 0.1で正確に表現できるわけではありません - したがって、バイナリ浮動小数点値を使用する場合、実際には0.1に近似されます。 浮動小数点も使用すると、近似値は得られます。たとえば、1を3で割った結果を正確に表すことはできません。

次の場合に使用するものについて:

  • 「自然に正確な小数点以下の桁数」の場合は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 by Decimalを置き換えた場合、bLowerには妥当な答えであるFALSEが含まれています。

二倍の問題は、fMean-fDelta = 1.09999999999が1.1よりも低いことです。

注意: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) 

これらのそれぞれの主な違いは精度です。

float32-bit数値、 double64-bit数値、 decimal128-bit数値です。


メモリとパフォーマンスの両方が重要なゲームや組み込みシステムのようなアプリケーションでは、浮動小数点型は通常倍精度のサイズの半分と高速であるため、数値型の選択肢です。 整数は選択の武器であったが、浮動小数点の性能は現代のプロセッサでは整数を凌駕している。 小数は間違いありません!


整数は、前述したように、整数です。 .7、.42、.007などの点を保存することはできません。 整数でない数値を格納する必要がある場合は、別のタイプの変数が必要です。 double型またはfloat型を使用できます。 これらのタイプの変数は、まったく同じ方法で設定しますintという単語を使用する代わりに、 doubleまたはfloatます。 このような:

float myFloat;
double myDouble;

floatは「浮動小数点」の略で、末尾に何か点がある数字を意味します)。

両者の違いは、それらが保持できる数値の大きさにあります。 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#は再び上下に丸められます。 道徳的なのは、正確さを望むならば、丸めに注意することです!


簡単な言葉で:

  1. Decimal、Double、およびFloat変数の型は、値を格納する方法が異なります。
  2. floatは単精度(32ビット)浮動小数点データ型、 doubleは倍精度(64ビット)浮動小数点データ型、 小数点は128ビットです。浮動小数点データ型。
  3. サマリーテーブル:

/==========================================================================================
    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)
/==========================================================================================
ここではFloatDouble 、およびDecimalを読むことができます。


精度が主な違いです。

Float - 7桁(32ビット)

Double -15-16桁(64ビット)

Decimal以下-28〜29桁有効数字(128ビット)

小数の精度ははるかに高く、通常は高度な精度が要求される金融アプリケーションで使用されます。 小数は、double / floatよりもはるかに遅い(いくつかのテストでは最大20倍)。

小数点以下の桁数と浮動小数点数は、キャストなしで比較することはできませんが、浮動小数点数と倍精度数は比較できます。 小数は、エンコードまたは末尾のゼロも許可します。

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

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

詳細については、以下を参照してください。
http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/921a8ffc-9829-4145-bdc9-a96c1ec174a5





decimal