Arithmetischer Überlauf

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Arithmetischer Überlauf

    Hallo,

    ich habe momentan ein Fehler-Problem wo ein Überlauf in einer 8Bit-Variable entsteht.

    VB.NET-Quellcode

    1. V((inst And &HF00) >> 8) += inst And &HFF

    nun möchte ich aber das diese zusammengerechnet werden und der Überlauf (bzw. das was zuviel wäre) einfach ignoriert wird. Try/Catch ist für mich da keine Lösung.

    Wie könnte ich nun dies bewerkstelligen?

    mfg & thx

    gfc
    Ich habe die Erfahrung gemacht, dass mehrmaliges Shiften in einer Zeile nicht funktioniert. Also ein Teil shiften, anderes Teil shiften und dann addieren, z.B. Wenn ich es auftrenne, in 2 Variablen und die dann addiere, dann geht es.

    Trenne die Zeile in mehrere Bestandsteile auf, jeweils eine Variable, die du dann auch richtig deklarierst. Auch Masken wie &HFF und &HF00 (muss es nicht &HFF00 sein?) als Variablen vom richtigen Datentyp deklarieren, es kann sonst durcheinander geraten, musst ausprobieren als was.

    Rechne dir (inst And &HF00) >> 8 extra in einer Variable aus, dann kannst du beim Debuggen auch schauen, welchen Wert sie hat. Und inst And &HFF auch extra.

    gfcwfzkm schrieb:

    VB.NET-Quellcode

    1. (inst And &HF00) >> 8
    Ist das ein Index?
    Bei kleinen Zahlen passiert da nix, nur dass Du mit Option Strict On das Ergebnis nach Byte casten musst.
    @sonne75 Jou.
    Mach da mal 3 Anweisungen draus, da kannst Du besser identifizieren, wo es knallt:

    VB.NET-Quellcode

    1. Dim i1 = (inst And &HF00) >> 8
    2. Dim i2 = inst And &HFF
    3. V(i1) += CByte(i2)

    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!
    Das mit dem Shiften klappt zum grössten teil. Nun hab ich mal im Debugger die Variablen ausgelesen und er möchte den Wert 0xFF (255) zu V(0), das den Wert 0x25 (37) hat, dazuaddieren. Nun möchte ich aber, das er mir kein Fehler angibt, sondern dies ausführt, also den Overflow ignoriert oder das was zuviel ist einfach entfernt. Geht das?

    EDIT:

    OptionStrict hab ich grad eingeschaltet, es sieht nun so aus:

    VB.NET-Quellcode

    1. V((inst And &HF00) >> 8) = CByte(V((inst And &HF00) >> 8) + (inst And &HFF))

    Aber der Fehler bleibt
    @gfcwfzkm

    RodFromGermany schrieb:

    Mach da mal 3 Anweisungen draus
    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!
    Noch immer der selbe Fehler:
    Bilder
    • errorpic.JPG

      259,22 kB, 1.680×1.011, 262 mal angesehen

    gfcwfzkm schrieb:

    Fehler
    Setze nun einen Haltepunkt drauf und sieh Dir die betroffenen Variablen an.
    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!

    gfcwfzkm schrieb:

    VB.NET-Quellcode

    1. V((inst And &HF00) >> 8) = CByte(V((inst And &HF00) >> 8) + (inst And &HFF))

    Aber der Fehler bleibt


    VB.NET-Quellcode

    1. V((inst And &HF00) >> 8) = CByte((V((inst And &HF00) >> 8) + (inst And &HFF)) And &HFF)

    ...wobei man das vordere "And &HFF" hierbei weglassen können müsste, sofern sich dabei nicht der Typ des Ausdrucks ändert.
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.
    Ich verstehe immer noch nicht, was du eigentlich erreichen willst.
    Du hast ein Byte und willst 0xFF dazu addieren, was natürlich nicht geht. Was ist der Sinn der Sache? Welcher Wert soll da drin stehen? Soll es auf 0xFF begrenzt werden?

    Dann prüf es doch vorher:

    VB.NET-Quellcode

    1. If CUShort(V(i1)+CByte(i2))>&HFF Then
    2. V(i1)=&HFF
    3. Else
    4. V(i1)+=CByte(i2)
    5. End If


    @Arby
    Stimmt, man könnte es auch so machen:

    VB.NET-Quellcode

    1. V(i1)=CByte(CUShort((V(i1)+CByte(i2)) And &HFF)


    Aber meins ist übersichtlicher.
    Sinn der Sache ist ein Chip8-Emulator/Interpreter. Steng genommen addiere nicht ich 0xFF, sondern ein altes Tetris-Spiel für den Chip8. Schätze das er so die Variable auf 0xFF setzten will, egal welchen Wert dieser hat.
    Mit Arby's Methode funktioniert es einwandfrei, danke.



    mfg & thx

    gfcwfzkm

    gfcwfzkm schrieb:

    Mit Arby's Methode funktioniert es einwandfrei, danke.


    Die Frage ist ob das Ergebnis auch das erwartete ist. Es ist nämlich leider nicht ganz klar - auch nach deiner Erläuterung und dem Screenshot nicht - was bei einem Überlauf eigentlich passieren soll.

    Soll jeglicher Wert, der beim Addieren über den maximal erlaubten Byte-Wert 255 hinausgeht, auf 255 "gedeckelt" oder alle "überlaufenden" Bits einfach weggeschnitten werden, d.h. nach 255+1 ergäbe wieder den Wert 0 usw.?

    Meine "Lösung" berücksichtigt den zweiten Fall. Da es sich offensichtlich um einen Bezug zu alten 8Bit-Konsolenspielen handelt, liegt die Annahme, dass dies tatsächlich ausreicht, sehr nahe - muss aber nicht zwangsläufig auch so sein.

    Also: Soll bei 255+10 der Wert 255 oder der Wert 9 (265 = &H109 => &H109 And &HFF = &H9) herauskommen?
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.
    Ou, hab wieder ein ähnliches Problem. Aber dieses mal muss ich den Überlauf "Abfragen/auslesen", damit ich das Carry-Flag setzten kann.

    VB.NET-Quellcode

    1. If (V(inst And &HF0) >> 4) > (&HFF - V((inst And &HF00) >> 8)) Then
    2. V(&HF) = 1 'VF = 1 bei Rest
    3. Else
    4. V(&HF) = 0
    5. End If

    Der Fehler passiert in der if-abfrage: Der Index war ausserhalb des Arraybereichs. Heisst dass, das er schon in der If-Abfrage überläuft?

    gfcwfzkm schrieb:

    Der Fehler passiert
    Wenn die Exception kommt, kannst Du Dir doch den Inhalt aller Variablen ansehen.
    Markiere eine arithmetische Operation, dann bekommst Du deren Ergebnis angezeigt.
    So brauchst Du keine 10 Sekunden, um den Fehler zu identifizieren :!:
    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!