如何在C#中更改NaN字符串表示?

我的程序将pointcloud保存到文件,其中每个pointcloud是来自System.Windows.Media.Media3D命名空间的Point3D[,] 。 这显示了输出文件的一行(用葡萄牙语):

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

虽然我希望它(为了以后正确解析):

 -112,644088741971;71,796623005014;NaN 

生成文件的代码块在这里:

 var lines = new List(); 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); 

似乎从Point3D.ToString()内部调用的double.NaN.ToString()方法包括括号中的“附加说明”,我根本不需要。

有没有办法更改/覆盖此方法,以便它只输出NaN ,没有括号部分?

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(); 

只是不要将NaN值传递给ToString

例如(包装在扩展方法中以便于重用):

 static string ToCleanString(this double val) { if (double.IsNan(val)) return "NaN"; return val.ToString(); } 

怎么样:

 NumberFormatInfo myFormatInfo = NumberFormatInfo.InvariantInfo; Point3D myPoint = new Point3D(1,1,double.NaN); var pointString = myPoint.ToString(myFormatInfo); 

首先,Caramiriel提供的答案是具有double.NaN的解决方案,您可能希望使用任何字符串。

顺便说一句,我想要字符串"NaN" ,这是文档对NumberFormatInfo.NaNSymbol说法:

表示IEEE NaN(非数字)值的字符串。 InvariantInfo的默认值是“NaN”。

然后我想通过使用InvariantCultureInfo提供的默认值,在创建当前线程之后添加以下行来找到如何使用我想要的纯“NaN”字符串并删除逗号分隔符:

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

这工作得很好!