Как изменить строковое представление NaN в C#?
моя программа сохраняет pointcloud в файл, где каждый pointcloud является 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 ответов
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);
чтобы установить это в текущем потоке, создайте копию текущей культуры и задайте информацию о числовом формате в культуре. Pre .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".
затем я понял, как получить желаемую чистую строку " NaN " и избавиться от запятой сепаратор, с помощью по умолчанию InvariantCultureInfo
, добавив складывающуюся строку сразу после создания текущего потока:
Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
и это сработало отлично!