Uint to Int Überlauf bei 0xFFFFFFFF

  • VB.NET

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von exc-jdbi.

    Uint to Int Überlauf bei 0xFFFFFFFF

    Hallo Zusammen,

    ich vertrete eine Kollegen, welcher in VB .NET ein tool geschrieben hat. Ich Selber Entwickle auf C++ und kenn den Fehler wie unten so nicht.

    Die arithmetische Operation hat einen Überlauf verursacht

    VB.NET-Quellcode

    1. Dim pos0 As UInt32 = returnVals(i)
    2. Dim pos1 As UInt32 = returnVals(i + 1)
    3. Dim pos2 As UInt32 = returnVals(i + 2)
    4. Dim pos3 As UInt32 = returnVals(i + 3)
    5. Dim newVal As UInt32 = pos0 * &H1000000
    6. newVal += (pos1 * &H10000)
    7. newVal += (pos2 * &H100)
    8. newVal += (pos3 * 1)
    9. Dim newValInt As Int32 = CInt(newVal)


    in der letzten Zeile, wo ich den Uint32 in einen Int32 wandeln möchte, wird folgender Fehler geworfen "Die arithmetische Operation hat einen Überlauf verursacht"
    hier noch die Ergebnisse er einzelnen Zeilen
    1. 255
    2. 255
    3. 255
    4. 255
    5. 4278190080
    6. 4294901760
    7. 4294967040
    8. 4294967295
    9.Die arithmetische Operation hat einen Überlauf verursacht

    Wo liegt denn Hier der Fehler?


    Fehler wurde behoben mit folgendem Code

    VB.NET-Quellcode

    1. Dim pos0 As UInt32 = returnVals(i)
    2. Dim pos1 As UInt32 = returnVals(i + 1)
    3. Dim pos2 As UInt32 = returnVals(i + 2)
    4. Dim pos3 As UInt32 = returnVals(i + 3)
    5. Dim newVal As UInt32 = pos0 * &H1000000
    6. newVal += (pos1 * &H10000)
    7. newVal += (pos2 * &H100)
    8. newVal += (pos3 * 1)
    9. Dim newValInt As Int32 = Convert.ToInt32(newVal.ToString("X8"), 16)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „zwick88“ ()

    Hallo,

    das Problem steckt eigentlich schon in der Fehlermeldung: Die Konvertierung von newVal (uint) zu newValInt (int) hat einen Überlauf verursacht. newVal stellt eine Zahl dar, die zu groß für den Typ Int32 ist.
    Ein Int kann maximal diesen Wert halten: docs.microsoft.com/en-us/dotnet/api/system.int32.maxvalue
    Wohingegen ein uint diesen hier speichern kann: docs.microsoft.com/en-us/dotnet/api/system.uint32.maxvalue?

    Die Lösung für das Problem hängt ein bisschen von der Aufgabe ab, die die erfüllen möchtest.
    Wenn du den zu großen Wert beibehalten möchtest, solltest du evtl. einfach beim uint bleiben und nichts konvertieren, oder aber ein long benutzen.
    Wenn du unbedingt einen int brauchst, kannst du z.B. mit Math.Min(int.MaxValue, newVal) hantieren. Das gibt dir dann maximal einen Wert zurück, der auch in einen int passt.
    Willkommen im Forum. :thumbup:

    zwick88 schrieb:

    VB.NET-Quellcode

    1. Dim newValInt As Int32 = CInt(newVal)
    Ersetze mal das CInt() durch Convert.ToInt32(), ich bin mir aber nicht ganz sicher, dass das funktioniert.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    zwick88 schrieb:

    Ich Selber Entwickle auf C++
    @exc-jdbi Greift leider nicht, denn in C++ ist eine solche Konvertierung völlig problemlos, anders als z.B. in C#.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    .. in C++ ergibt int newValInt = 4294967295 wie Eierlein schreibt -1.

    und in VB.NET auch. Vorausgesetzt man hat die in meinem Link erwähnte Einstellung umgestellt.

    Es stellt sich nur die Frage, ob man mit dem Resultat zufrieden ist.

    Edit:
    Mir ist jetzt noch das eingefallen, sofern man die Einstellungen nicht verändern möchte.
    Funktioniert natürlich auch in C++

    Ungetestet:

    VB.NET-Quellcode

    1. Private Function Ui32ToI32(ui32 As UInt32) As Int32
    2. Return If(ui32 <= Int32.MaxValue,
    3. CInt(ui32 And Int32.MaxValue),
    4. CInt(ui32 And Int32.MaxValue) Or Int32.MinValue)
    5. End Function
    6. Private Function I32ToUi32(i32 As Int32) As UInt32
    7. Return CUInt(i32 And UInt32.MaxValue)
    8. End Function


    Freundliche Grüsse

    exc-jdbi

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „exc-jdbi“ ()