2

In my locale, double.Parse("Infinity") returns double.PositiveInfinity, but double.Parse("infinity") throws System.FormatException. Analogous things happen for negative infinity and NaN.

I could obviously just use CultureInfo.CurrentCulture.NumberFormat.PositiveInfinitySymbol.Equals() with a case-insensitive comparison to check for a match before calling double.Parse() (and do likewise for negative infinity and NaN). However, I was hoping for something more elegant.

Jude Melancon
  • 462
  • 5
  • 11
  • What is your `CurrentCulture`? – Soner Gönül Aug 18 '14 at 14:08
  • @Soner Mine happens to be en-US with a date format tweak, but I would like to support arbitrary CurrentCulture values. – Jude Melancon Aug 18 '14 at 14:11
  • Do you want to support the names of the current culture, so if it's "de-DE" `"+unendlich"` should be detected successfully as `PositiveInfinitySymbol`? It's not clear whether the input is controlled by you or not. – Tim Schmelter Aug 18 '14 at 14:12
  • @Tim If the user's `CurrentCulture` is de-DE, I would like "+unendlich" (which _is_ `PositiveInfinitySymbol`) to parse successfully as `double.PositiveInfinity`. I would also like "+Unendlich" and "UNENDLICH" to parse to the same value. The input is from a user. – Jude Melancon Aug 18 '14 at 14:16

3 Answers3

1

I don't see much option beyond doing a TryParse(), and, on failure, special-casing the three special tokens as is shown in Number.ParseDouble() and double.TryParse(). I'd do the check after rather than before since, in most cases, this won't happen.

dbc
  • 104,963
  • 20
  • 228
  • 340
  • Your reference links are convincing evidence there's no better way. I also like your suggestion of doing the rare case as a second effort instead of before the common path. – Jude Melancon Aug 18 '14 at 14:22
1

Looking at the Parse method for double, it doesn't look like you have a lot of wiggle room:

// 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;
}

Since the Equals method that is used here doesn't let you change case sensitiveness, I think that you should investigate in custom extensions for your parsing, perhaps adding a AsDouble method on top of string.

samy
  • 14,832
  • 2
  • 54
  • 82
0

Do you want to support the names of the current culture, so if it's "de-DE" "+unendlich" should be detected successfully as PositiveInfinitySymbol? It's not clear whether the input is controlled by you or not.

You:

If the user's CurrentCulture is "de-DE", I would like "+unendlich" (which is PositiveInfinitySymbol) to parse successfully as double.PositiveInfinity. I would also like "+Unendlich" and "UNENDLICH" to parse to the same value.

Then your approach absolutely fine, isn't it? You could write a method like this:

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;
}

and use it in this way:

string doubleStr = "+UNENDLICH";
double d;
bool success = ParseDoubleExt(doubleStr, out d);
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939