Как мне анализировать числа с плавающей запятой и удваивать их без учета регистра в C# (для покрытия "бесконечности" и т. Д.)?

В моем регионе, double.Parse("Infinity") возвращается double.PositiveInfinity, но double.Parse("infinity") бросает System.FormatException, Аналогичные вещи случаются для отрицательной бесконечности и NaN.

Я мог бы просто использовать CultureInfo.CurrentCulture.NumberFormat.PositiveInfinitySymbol.Equals() с учетом без учета регистра для проверки соответствия перед вызовом double.Parse() (и сделать так же для отрицательной бесконечности и NaN). Однако я надеялся на что-то более элегантное.

3 ответа

Решение

Я не вижу большого выбора, кроме как сделать TryParse() и, в случае ошибки, в специальном корпусе три специальных токена, как показано в Number.ParseDouble() а также double.TryParse(), Я бы сделал проверку после, а не раньше, так как в большинстве случаев этого не произойдет.

Глядя на Parse метод double, не похоже, что у вас много места для маневра:

// double
private static double Parse(string s, NumberStyles style, NumberFormatInfo info)
{
    double result;
    try
    {
        result = Number.ParseDouble(s, style, info);
    }
    catch (FormatException)
    {
        string text = s.Trim();
        if (text.Equals(info.PositiveInfinitySymbol)) // case-sensitive comparison
        {
            result = double.PositiveInfinity;
        }
        else
        {
            if (text.Equals(info.NegativeInfinitySymbol)) // case-sensitive comparison
            {
                result = double.NegativeInfinity;
            }
            else
            {
                if (!text.Equals(info.NaNSymbol)) // case-sensitive comparison
                {
                    throw;
                }
                result = double.NaN;
            }
        }
    }
    return result;
}

Так как Equals метод, который используется здесь, не позволяет вам изменять чувствительность к регистру, я думаю, что вы должны исследовать пользовательские расширения для своего анализа, возможно, добавив AsDouble метод поверх string,

Вы хотите поддержать названия текущей культуры, так что если это "де-де" "+unendlich" должен быть успешно обнаружен как PositiveInfinitySymbol? Непонятно, контролируете ли вы вход или нет.

Вы:

Если пользователь CurrentCulture это "де-де", я хотел бы "+ undndlich" (что PositiveInfinitySymbol) успешно разобрать как double.PositiveInfinity, Я также хотел бы, чтобы "+Unendlich" и "UNENDLICH" анализировали одно и то же значение.

Тогда ваш подход абсолютно хорошо, не так ли? Вы можете написать такой метод:

public static bool ParseDoubleExt(string input, out double doubleVal, StringComparison comparison = StringComparison.CurrentCultureIgnoreCase, NumberFormatInfo nfi = null)
{
    if (nfi == null)
        nfi = NumberFormatInfo.CurrentInfo;
    doubleVal = double.MinValue;
    double d;

    if (double.TryParse(input, out d))
    {
        doubleVal = d;
        return true;
    }
    else
    {
        bool isPosInf = nfi.PositiveInfinitySymbol.Equals(input, comparison);
        if (isPosInf)
        {
            d = double.PositiveInfinity;
            return true;
        }
        bool isNegInf = nfi.NegativeInfinitySymbol.Equals(input, comparison);
        if (isNegInf)
        {
            d = double.NegativeInfinity;
            return true;
        }
        bool isNAN = nfi.NaNSymbol.Equals(input, comparison);
        if (isNAN)
        {
            d = double.NaN;
            return true;
        }

        // to be extended ...
    }
    return false;
}

и использовать его таким образом:

string doubleStr = "+UNENDLICH";
double d;
bool success = ParseDoubleExt(doubleStr, out d);
Другие вопросы по тегам