Frage

Ich habe diese Zeichenfolge „1.79769313486232E + 308“ und ich versuche, es zu einem .NET-numerischen Wert zu konvertieren (Doppel?), Aber die unten Ausnahme bin immer. Ich verwende Convert.ToDouble(). Was ist der richtige Weg, um diese Umwandlung zu tun?

  

Overflow: Wert entweder zu groß oder zu klein für ein Doppel war

War es hilfreich?

Lösung

Das Problem ist wahrscheinlich aufgrund der Tatsache, dass Double.MaxValue in einen String umgewandelt wurde, und wenn die Zeichenfolge ausgegeben wird, nicht alle Stellen ausgegeben werden, sondern es wird abgerundet. diesen Wert Parsen überläuft das Doppelte.

Double.TryParse Verwendung und anschließend Gleichheit auf der Zeichenfolge „1.79769313486232E + 308“ im Fall des Scheiterns Überprüfung und Ersetzen Double.MaxValue sollte eine schnelle Abhilfe, wenn Sie die Zeichenfolge so, wie es ist halten müssen.

EDIT: Natürlich, wenn Sie es nicht, dass die Zeichenfolge, die die Art und Weise halten müssen, verwenden Sie die Round Trip Formatspezifizierer die Zeichenfolge in erster Linie, wie Jon beschreibt in seiner Antwort .

Andere Tipps

Leider ist dieser Wert größer als double.MaxValue, damit die Ausnahme.

Wie codekaizen schon sagt, Sie hart Code ein Test für die Zeichenfolge konnte. Eine bessere (IMO) Alternative, wenn Sie derjenige sind produziert die Zeichenfolge in erster Linie ist die „r“ Formatangabe zu verwenden. Dann wird die Zeichenfolge, die Sie produzieren sein „1.7976931348623157E + 308“ statt, die dann richtig analysiert:

string s = double.MaxValue.ToString("r");
double d = double.Parse(s); // No exception

Natürlich, das ist keine Hilfe, wenn Sie keine Kontrolle über die Daten haben -. Aber dann sollten Sie verstehen, Sie werden sie wahrscheinlich bereits Daten in diesem Fall verlieren

Sie können versuchen double.Parse() oder double.TryParse() anstatt Convert.ToDouble(), aber ich bin nicht sicher, Sie werden bessere Ergebnisse. Im Übrigen ist die Zeichenfolge, die Sie liefern gleich double.MaxValue, die (natürlich) ist der Maximalwert, der in einem Doppel enthalten sein können, so dass wahrscheinlich, wo Ihre Fehler herkommt. Fließkommazahlen-Typen sind heikel, also würde ich davon ausgehen, dass eine Art von Rundung stattfindet und es außerhalb der Grenzen des Typs drücken.

Sie können auch den decimal Datentyp versuchen. Sie können dort mehr Glück haben.

Hier ist, was ich kam mit. Dank Jon Skeet und codekaizen.

private double convertToDouble(string str)
{
    double dbl;

    if (double.TryParse(str, out dbl))
        return dbl;

    if (str == "1.79769313486232E+308")
        return double.MaxValue;

    return double.MinValue;
}

Demonstriert das Problem und eine Lösung:

var s = double.MaxValue.ToString();
double d;
if (!double.TryParse(s, out d)) {
    d = s.Equals(double.MaxValue) ? double.MaxValue : double.MinValue;
}

Hier ist eine generische Implementierung, die unterschiedlichen Formatierungen und Kulturen darstellen und ist toleranter:

#region MatchDoubleMinMaxValuesRegex
/// <summary>
/// This regex matches strings which represents either a <see cref="double.MinValue"/> or a <see cref="double.MaxValue"/>.
/// If it is a <see cref="double.MinValue"/> then the group "isNegative" will be matched as <see cref="Group.Success"/>.
/// </summary>
private static readonly Regex MatchDoubleMinMaxValuesRegex = new Regex(
    @"
        ^
        (?>(?<isNegative>-)|\+?)
        1
        (?>[,.]?)
        79769313486232
        (?>
            [eE]\+308|
            0{294}(?>[,.]|$)
        )
    ",
    RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace
);
#endregion

/// <summary>
/// Converts the string representation of a number in a specified culture-specific format to its double-precision floating-point number equivalent.
/// <para>This implementation is more tolerant compared to the native double.Parse implementation:
/// strings representing <see cref="double.MinValue"/> and <see cref="double.MaxValue"/> can be parsed without <see cref="OverflowException"/>.</para>
/// </summary>
/// <param name="s">A string that contains a number to convert.</param>
/// <param name="cultureInfo">For some type conversions optional culture information that shall be used to parse the value.
/// If not specified, then the Current Culture will be used.</param>
/// <param name="numberStyles">For some type conversions optional number style configuration that shall be used to parse the value.
/// If not specified, then the default will be used.</param>
/// <returns>A double-precision floating-point number that is equivalent to the numeric value or symbol specified in <paramref name="s"/>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="s"/> is <c>null</c>.</exception>
/// <exception cref="FormatException"><paramref name="s"/> does not represent a number in a valid format.</exception>
/// <exception cref="OverflowException"><paramref name="s"/> represents a number that is less than <see cref="double.MinValue"/> or greater than <see cref="double.MaxValue"/>.</exception>
public static double ParseDoubleEx(string s, CultureInfo cultureInfo = null, NumberStyles? numberStyles = null)
{
    // Try parse
    double tempValue;
    bool parseSuccess = (numberStyles != null)
        ? double.TryParse(s, numberStyles.Value, cultureInfo, out tempValue)
        : double.TryParse(s, NumberStyles.Any, cultureInfo, out tempValue);

    // If parsing failed, check for Min or Max Value (by pattern)
    if (parseSuccess == false)
    {
        Match match = MatchDoubleMinMaxValuesRegex.Match(s);
        if (match.Success == true)
            tempValue = (match.Groups["isNegative"].Success == false)
                ? double.MaxValue
                : double.MinValue;
        else
            throw new OverflowException("A double-precision floating-point number that is equivalent to the numeric value or symbol specified in s.");
    }

    return tempValue;
}

Diese Zahl ist zu groß für ein Doppelzimmer, als die Ausnahme, sagt. Sie werden eine große Anzahl Bibliothek haben, um herauszufinden, dass für Sie zu handhaben, da es nichts gibt, was ich von der Net-Bibliothek kennen, die sehr große Zahlen behandelt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top