8

私のプログラムは、ポイントクラウドをファイルに保存します。各ポイントクラウドはPoint3D[,]System.Windows.Media.Media3D名前空間から です。これは、出力ファイルの行を示しています (ポルトガル語):

-112,644088741971;71,796623005014;NaN (Não é um número)

私はそれをしたいのですが(後で正しく解析するために):

-112,644088741971;71,796623005014;NaN

ファイルを生成するコード ブロックは次のとおりです。

var lines = new List<string>();

for (int rows = 0; rows < malha.GetLength(0); rows++) {
    for (int cols = 0; cols < malha.GetLength(1); cols++) {

        double x = coordenadas_x[cols];
        double y = coordenadas_y[rows];
        double z;

        if ( SomeTest() ) {
            z = alglib.rbfcalc2(model, x, y);
        } else {
            z = double.NaN;
        }

        var p = new Point3D(x, y, z);
        lines.Add(p.ToString());                       

        malha[rows, cols] = p;
    }
}

File.WriteAllLines("../../../../dummydata/malha.txt", lines);

double.NaN.ToString()内部から呼び出されたメソッドには、括弧で囲まれた「追加の説明」が含まれているようですが、Point3D.ToString()これはまったく必要ありません。

このメソッドを変更/オーバーライドしてNaN、括弧部分なしで のみを出力する方法はありますか?

4

4 に答える 4

11

Double.ToString()NumberFormatInfo.CurrentInfo数値をフォーマットするために使用します。この最後のプロパティCultureInfoは、アクティブなスレッドに現在設定されているを参照します。これはデフォルトでユーザーの現在のロケールになります。この場合、それはポルトガルの文化の設定です。この動作を回避するには、Double.ToString(IFormatProvider)オーバーロードを使用します。この場合、を使用できますCultureInfo.InvariantCulture

さらに、他のすべてのマークアップを保持したい場合は、NaNシンボルを切り替えることができます。デフォルトでは、グローバリゼーション情報は読み取り専用です。クローンを作成すると、これを回避できます。

System.Globalization.NumberFormatInfo numberFormatInfo = 
    (System.Globalization.NumberFormatInfo) System.Globalization.NumberFormatInfo.CurrentInfo.Clone();
numberFormatInfo.NaNSymbol = "NaN";

double num = double.NaN;
string numString = System.Number.FormatDouble(num, null, numberFormatInfo);

これを現在のスレッドに設定するには、現在のカルチャのコピーを作成し、カルチャに数値形式情報を設定します。.NET 4.5より前では、すべてのスレッドに設定する方法はありません。各スレッドを作成した後、正しいことを確認する必要がありますCultureInfo。.NET 4.5以降、。CultureInfo.DefaultThreadCurrentCulture内のスレッドのデフォルトカルチャを定義するものがありますAppDomain。この設定は、スレッドのカルチャがまだ設定されていない場合にのみ考慮されます(MSDNを参照)。

シングルスレッドの例:

System.Globalization.CultureInfo myCulture =
     (System.Globalization.CultureInfo)System.Threading.Thread.CurrentThread.CurrentCulture.Clone();
myCulture.NumberFormat.NaNSymbol = "NaN";

System.Threading.Thread.CurrentThread.CurrentCulture = myCulture;   
string numString = double.NaN.ToString();
于 2013-03-08T18:51:33.430 に答える
1

NaN 値を に渡さないでくださいToString

例(簡単に再利用できるように拡張メソッドでラップ):

static string ToCleanString(this double val)
{
    if (double.IsNan(val)) return "NaN";
    return val.ToString();
}
于 2013-03-08T18:56:19.073 に答える
0

まず第一に、Caramiriel が提供する答えは、double.NaNあなたが望むかもしれない任意の文字列で表されるソリューションです。

ちなみに、私は文字列が欲しいのですが"NaN"、ここにドキュメントの内容がありますNumberFormatInfo.NaNSymbol:

IEEE NaN (数値ではない) 値を表す文字列。InvariantInfo のデフォルトは「NaN」です。

InvariantCultureInfo次に、現在のスレッドが作成された直後に次の行を追加し、によって提供されるデフォルトを使用して、目的の純粋な「NaN」文字列を取得し、コンマ区切り記号を取り除く方法を考え出しました。

Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;

そして、それはうまくいきました!

于 2013-03-08T19:43:09.967 に答える
0

どうですか:

NumberFormatInfo myFormatInfo = NumberFormatInfo.InvariantInfo;

Point3D myPoint = new Point3D(1,1,double.NaN);
var pointString = myPoint.ToString(myFormatInfo);
于 2013-03-08T19:10:24.237 に答える