2

「完全な精度」とは、正しい結果がC#プログラムで計算した結果と異なる場合がないことを意味します。

C#とC ++で同じテストを実行して(cout.precision()を使用せずに)これを確認しました。C#とC ++での私のプログラムの2つのバリアントは、同じテストで同じように動作すると確信しています。

C#のサンプルコード。

double a;
//...code...
Console.WriteLine(a.ToString(CultureInfo.InvariantCulture));

同じですが、C++です。

double a;
//...code...
cout << a << endl;

実際、cout.precision()を使用しないC ++プログラムは失敗し、Console.WriteLine()のみを使用するC#は成功しました。

これは、C ++プログラムが何らかの方法で(おそらく魔法のように)数値を切り捨て、精度が失われるために発生することを知っています。しかし、すべてのテストに合格するということは、C#が常に完全な精度でdoulbe変数を出力することを意味しますか?

4

3 に答える 3

5

「R」フォーマット指定子を使用してdoubleをフォーマットすると、「ラウンドトリップ」表現が得られます。詳細については、 http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx#RFormatStringを参照してください。使用法:

string s = someDoubleValue.ToString("R");

デフォルトのフォーマット指定子は、指定されていない場合、「G」(一般)です。これは、「数値のタイプと精度指定子が存在するかどうかに応じて、数値を固定小数点表記または科学的記数法の最もコンパクトなものに変換します。 。」詳細については、 http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx#GFormatStringを参照してください。精度指定子が指定されていない場合、double15桁の精度が得られるため、「G」を使用すると精度が低下する可能性があります。

于 2012-10-02T20:30:21.503 に答える
3

C ++とC#はどちらも、浮動小数点数を2進数として格納します。基数2で64ビット表現を持つすべての数値が、基数10で適度に長い表現を持つわけではありません。doubleたとえば、15桁の小数に変換する場合、丸めが必ず発生します。

違いが見られる理由は、2つの言語が、印刷時に基数2を基数10に変換するためのデフォルトの精度の選択が異なるためです。(必要な場所で四捨五入される出力精度で印刷することにより、カスタマイズできる選択肢。)

于 2012-10-02T20:29:57.393 に答える
1

double値の正確な小数表現は数十か所に及ぶ可能性があるため、その点での答えは「いいえ」です。有限の数値の10進数文字列と有限の数値の2進数のdoubleを1対1で対応させるのに十分な精度を保証するラウンドトリップ形式があります(NaNと無限大をどのように処理するかはわかりません)が、ToStringは使用しません指定しない限りその形式( "R")なので、その点での答えもノーです。

実際、このオーバーロードを使用すると、「G」フォーマット指定子に従ってフォーマットされた結果が得られます(Double.ToStringメソッド(IFormatProvider)を参照)。

すべての標準指定子については、「標準数値形式文字列」を参照してください。

Jon Skeetには、doubleを(おそらく非常に長い)正確な10進表現に変換するクラスがあります。関連する記事はここにあります:http://csharpindepth.com/Articles/General/FloatingPoint.aspx ; クラス自体はここにあります:http ://www.yoda.arachsys.com/csharp/DoubleConverter.cs

于 2012-10-02T20:32:49.913 に答える