2016-11-14 11 views
1

1.123456789123456789123456789E-28のような値を生成する古いVBAアプリケーションがあります。私がC#で同等のデータ型を見つけようとしたとき、私はこの記事をSO Difference between decimal, float and double in .NET?に見つけました。この投稿が示唆しているとおり、10進データ型はC#で最大のサイズです。だから私は10進データ型を使用しましたが、VBAが指数関数形式で表現する大きな値を表現するには小数点の数が限られているようです。だから私は再びgoogledとこの記事を見つけたhttps://msdn.microsoft.com/en-us/library/ae55hdtk.aspx。この記事で述べたように、VBA指数形式のC#データ型

非整数値はMMMに、mmmEeeeように表すことができる 仮数(有効桁)とEEE指数(電源10の )です。非整数型の正の最大値は、小数の場合は 7.9228162514264337593543950335E + 28、単精度の場合は3.4028235E + 38、倍精度の場合は1.79769313486231570E + 308です。

これは、ダブルデータ型が最大値の範囲を持つことを意味します。だから私は10進数と2倍の間で混乱しています。それは0.0000000000000000000000000001にDCL値が変化しながら1.123456789123456789123456789E-28であるようにDBL値を出力し

double dbl = 1.123456789123456789123456789E-28; 
    decimal dcl = 1.123456789123456789123456789E-28M; 
    MessageBox.Show(dbl.ToString()); 
    MessageBox.Show(dcl.ToString()); 

以下のよう

そしてIはコードで少し実験を行いました。 誰かがここで何が起こっているのか説明できますか?同じ精度のVBAのような大きな指数値を表すために、C#の同等のデータ型は何ですか?

+2

最初の記事をさらに読むと、その違いや使い方を理解できます。私はあなたが投稿した最初のリンクを誤解しているかもしれないと思います。 – Hank

答えて

4

C#言語仕様によると:https://msdn.microsoft.com/en-us/library/aa691085%28v=vs.71%29.aspx

  • FまたはFサフィックス実数リテラルはfloat型です。たとえば、リテラル1f、1.5f、1e10f、および123.456Fはすべてfloat型です。
  • Dまたはdの後に接尾語が現れる実数型はdouble型です。たとえば、リテラル1d、1.5d、1e10d、および123.456Dはすべてdouble型です。
  • Mまたはmの接尾辞付き実数はdecimal型です。たとえば、リテラル1m、1.5m、1e10m、および123.456Mはすべて10進数の型です。 このリテラルは、正確に の値をとり、必要に応じて、バンカーの丸めを使用して最も近い表現可能な値 (第4.1.7項)に丸めて10進数値に変換します。 リテラルで明らかなスケールは、値が四捨五入されていないか、値がゼロの場合を除いて保存されます。 (後者の場合は符号と位取りが0になります)。したがって、 リテラル2.900mは、符号0、 係数2900、および位取り3の小数部を構成するように解析されます。

3番目の箇条書きを見ると、あなたは「このリテラルは正確な値...を取ることによって、小数点値に変換されています...」というフレーズを見ることができます。あなたが得ている値(0.0000000000000000000000000001)は、あなたが始まった入力リテラル(1.123456789123456789123456789E-28M)の変換結果です。もちろん、換算に関する第3の箇条書きの第2部の値に丸めた値は、「...必要に応じて、銀行家の丸めを使用して最も近い表現可能な値に丸める...」となります。

これはdecimalでも当てはまりますが、floatまたはdoubleの場合、データ型自体で指数表記を保存できるため、変換/丸め処理は必要ありません。

追加:

は、上記にさらに拡大するには、以下を参照してください。https://msdn.microsoft.com/en-us/library/364x0z75.aspx

これはdecimalデータ型の定義です。そこに記載されているように、decimalの範囲は(-7.9 x 1028 to 7.9 x 1028)/(100 to 28)または28 to 29 significant digitsです。あなたの文字列、1.123456789123456789123456789E-28Mはその限界を超えているので、変換されると、1の右側のすべてが上記の規則に従って丸められます。

ソリューション(?):

あなたはdecimalが提供できるよりも大きな精度を必要とする場合、あなたは間違いなくなんとかです独自のクラスを実装するに見てみたいことがあります。アイデアはBigDecimalのC#実装を検索することを検討してください。私は簡単にGoogleで見つけ

一実施:https://gist.github.com/nberardi/2667136

は、私はその正しさに話すことはできませんが、それは、少なくともあなたのための出発点である可能性があります。

1

floatおよびdoubleは浮動小数点数です。これは、数値と指数係数を分離して保持していることを意味します。doublefloatの倍精度です。 doubleは、価格など重要度が重要な場合に使用することはお勧めしません。
decimalは、固定小数点で「小数」形式の数字を保持しています。特に小数点の計算では、より正確です。
doubleがあなたが探しているものである可能性が高いと思われます。