2015-07-22 2 views
2

У меня есть некоторые распространенные методы для синтаксического анализа с переопределением значений по умолчанию при чтении в некоторых старых данных Fortran. Иногда данные имеют NaN (Not a number), где должно быть числовое значение. Я ожидал, что TryParse увидит строку «NaN» и не будет разбираться. Однако TryParse успешно разбирает и помещает NaN в числовое значение. Это ожидаемое поведение? Если это ожидается, есть ли какие-либо другие значения «gotcha», которые я должен искать?Почему C# TryParse не обрабатывает NaN?

public static double GetDoubleFromString(string s, double defaultOnFailure = 0) 
    { 
     //Must be here due to TryParse returning NaN to d and result is set to true below 
     if (s.Contains("NaN")) 
     { 
      log.Warn(string.Format("String contained NaN, returning defaultOnFailure {0} string was {1}", defaultOnFailure, s)); 
      return defaultOnFailure; 
     } 

     var d = defaultOnFailure; 
     if (!double.TryParse(s.Trim(), out d)) 
     { 
      log.Warn(string.Format("Failed to parse double from string returning defaultOnFailure {0} string was {1}", defaultOnFailure, s)); 
     } 

     return d; 
    } 

UPDATE

Я чувствую, что следует отметить, что это происходит только для двойной, длинный и INT не возвращает значение NaN. См. Пример кода ниже, код Common .... просто отформатирован Console.WriteLine или останавливается для выполнения консоли. См. Снимок экрана ниже.

public static void NanTestMain() 
    { 
     Common.WriteBlankWithTitle("Test parse NaN"); 
     string s = "NaN"; 

     Common.WriteBlankWithTitle("NaN to Int"); 
     int i; 
     var intSuccess = int.TryParse(s, out i); 
     Console.WriteLine(string.Format("Int parse of {0} parse = {1}", i, intSuccess)); 

     Common.WriteBlankWithTitle("NaN to Double"); 
     double d; 
     var doubleSuccess = double.TryParse(s, out d); 
     Console.WriteLine(string.Format("Double parse of {0} parse = {1}", d, doubleSuccess)); 

     Common.WriteBlankWithTitle("NaN to Long"); 
     long l; 
     var longSuccess = long.TryParse(s, out l); 
     Console.WriteLine(string.Format("Long parse of {0} parse = {1}", l, longSuccess)); 

     Common.Pause(); 
    } 

Results of Update Code

ответ

9

MSDN От:

В сек параметр может содержать NumberFormatInfo.PositiveInfinitySymbol, NumberFormatInfo.NegativeInfinitySymbol или NumberFormatInfo.NaNSymbol для культуры, указанной поставщиком.

Существует три «специальных» значения, которые необходимо учитывать. Тем не менее, последние несколько слов являются ключевыми - в зависимости от текущей культуры, вы можете увидеть что-то отличное от "NaN"!

+0

И с каждым днем ​​я нахожу, что знаю меньше. Спасибо, что ответили (со ссылками) на все мои вопросы. – JabberwockyDecompiler

+1

Я не знал о существовании этих символов, пока вы не задали этот вопрос. Вам также может понравиться http://stackoverflow.com/q/26428080/3140 для получения информации о других параметрах 'Double.TryParse', в зависимости от вашего варианта использования. –

3

Double.NaN является допустимым значением для двойной, так что это нормально. Существует также отрицательная и положительная бесконечность. Проверьте here на другие возможные «специальные» значения.

+0

Ответ Джейкоба был немного ближе к ссылке MSDN, это по-прежнему полезно. – JabberwockyDecompiler