Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » Java » byte overflow abfangen

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
18.03.2010, 22:49 Uhr
Meuterich



Hallo Leutz,

habe da Problem bekommen an dem ich schon ein Weilchen knabber.
Rechnen mit byte-Variablen.
Gibt es eine Moeglichkeit den Overflow beim Rechnen mit byte-Variablen abzufangen? Bei sowas z. B.:


Code:
byte a = (byte) 120;
byte b = (byte) 30;
byte c = (byte) 0;
c = (byte) (a + b);



Alles groesser als byte ist nicht zulaessig. Gibt es da ne try{}catch Loesung fuer? Ich hab da nichts in der API oder dem Internet gefunden. Ich weiss aber auch nicht so wirklich wonach ich da suchen soll. Sonst hab ich immer einfach dann nen groesseren Datentyp genommen, aber es ist ja nicht immer vorher ersichtlich ob es zu einem Overflow kommen wird. Kann man sowas abfangen und wenn ja wie?

Kann mit da wer weiterhelfen?

Gruesse,
Meuterich
--
Eine Signatur wird unter jedem von Ihnen erstellten Beitrag angefügt.
Maximal 5 Linien, jedoch nicht mehr als 600 Zeichen.
ThWboard-Code-Tags werden bis auf [url] und [img] nicht berücksichtigt.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
19.03.2010, 01:30 Uhr
0xdeadbeef
Gott
(Operator)


Etwas in der Art?

C++:
if((a < 0 ? -127 : 128) - a > b) {
  // wirf Exception
}



Bearbeitung:

Tipfeeler.


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 19.03.2010 um 02:50 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
19.03.2010, 01:53 Uhr
Hans
Library Walker
(Operator)


Hi,

das ist 'ne gute Frage. Ich kenn da eigentlich nur die Lösungen auf Assemblerebene, da würde man halt bestimmte Flags des Prozessorstatusregisters abfragen.

Ansonsten kann man sich mit Bitoperationen behelfen, etwa so:

C++:
#include <stdio.h>

int main()
{
  typedef   signed char sbyte;
  typedef unsigned char byte;
  
  byte  a = 120;
  byte  b =  30;
  byte  c =   0;
  sbyte d =   0;

  int vgl;
  c = a + b;
  d = a + b;
  printf ("c=%d, \t d=%d ", c, d);

  if ((c & 0x80) == 128) printf ("Überlauf.\n");

  a = 250;
  c = a + b;
  vgl = a + b;
  printf ("c=%d, \t vgl=%d ", c, vgl);
  if (vgl > 255) printf ("Überlauf.");
  if ((vgl & 0xff) != 0) printf ("Überlauf.");
  
  return 0;
}


Das wirft zwar keine Exceptions, funktioniert aber.

Jetzt seh ich aber gerade auch, dass das hier ja die Java-Abteilung ist, da weis ich gar nicht, ob die Bitoperationen von C/C++ da überhaupt funktionieren...

Hans
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
19.03.2010, 02:48 Uhr
0xdeadbeef
Gott
(Operator)


In aller Regel ist das Verhalten von Überläufen in Programmiersprachen nicht definiert, also gibt es keine allgemeingültige Lösung. Wenn man Überläufe befürchtet, ist es sinnvoller, vor der Operation, die einen Überlauf erzeugen könnte, zu prüfen, ob sie mit den gegebenen Eingabedaten einen Überlauf erzeugen würde. So wie oben beschrieben halt - für Addition generell in der Form


Code:
if((a < 0 ? TYP_MIN : TYP_MAX) - a > b) {
  // a + b wird überlaufen
}



In diesem speziellen Fall könnte man natürlich auch nach int casten, damit rechnen und dann prüfen, ob das Ergebnis in ein Byte passt.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 19.03.2010 um 02:49 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
21.03.2010, 11:39 Uhr
Meuterich



Hallo,

scusi weils so lange mit ner Antwort gedauert hat.
0xdeadveaf, leider funzt das was Du da geschrieben hast nicht bei mir mit Java, ist wohl C oder? Was bedeutet denn das ? und das - ist mir auch nicht ganz klar. Wird da das Ergebnis der Logikaussage von einander subtrahiert?

Hm, das bloede ist wirklich, dass, wenn ich z. B. eine Zuweisung mache wie byte = int dann wirds erst garnicht kompiliert und wenn ich dann nen Typecast mache byte = (byte) int wird kompiliert aber der Ueberlauf ist da. Ich fuerchte das ueberfordert mich grad, rechne ich also mit int.
Aber interessant waers trotzdem irgendwie...

Danke jedenfalls
m.
--
Eine Signatur wird unter jedem von Ihnen erstellten Beitrag angefügt.
Maximal 5 Linien, jedoch nicht mehr als 600 Zeichen.
ThWboard-Code-Tags werden bis auf [url] und [img] nicht berücksichtigt.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
21.03.2010, 14:31 Uhr
~toxic
Gast


Hi,

das mit dem "?" ist ein if-else konstruct, man könnte auch schreiben:

C++:
byte x = (a < 0 ? TYP_MIN : TYP_MAX);
// ist das selbe wie
byte x;
if ( a < 0 )
    x = TYP_MIN;
else
    x = TYP_MAX;


du müsstest eben das ganze dann erweitern

C++:
if ( (a < 0 && (TYP_MIN - a) > b) || (a > 0 && (TYP_MAX - a) > b) )
{
  // a + b wird überlaufen
}

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
29.03.2010, 20:14 Uhr
~SagIchDirNicht
Gast



Zitat:

Gibt es eine Moeglichkeit den Overflow beim Rechnen mit byte-Variablen abzufangen? Bei sowas z. B.:

C++:
byte a = (byte) 120;
byte b = (byte) 30;
byte c = (byte) 0;
c = (byte) (a + b);





Java bietet von Hause aus keine Prüfung auf einen Overflow an, du musst wie meine Vorgänger selber auf einen Overflow prüfen und zwar immer mit einem Nächst höheren Wert. Am besten du nimmst für eine Addition immer einen

Hier ein kleines Beispiel für ganz Zahl Datentypen:


C++:
package com.betasystems.data.adapter;

import java.math.BigInteger;

public class Overflow {
    /**
     * Exception wird geworfen sobald ein Overflow auftritt
     *
     * @author Yves
     *
     */

    public static class OverlowException extends Exception {


        public OverlowException() {
            super();
            // TODO Auto-generated constructor stub
        }

        public OverlowException(String message, Throwable cause) {
            super(message, cause);
            // TODO Auto-generated constructor stub
        }

        public OverlowException(String message) {
            super(message);
            // TODO Auto-generated constructor stub
        }

        public OverlowException(Throwable cause) {
            super(cause);
            // TODO Auto-generated constructor stub
        }

    }
    
    /**
     * Prüfe für die Typen Byte,Short,Integer und
     * Long ob sich die Zahlen a und b ohne einen Overlow addieren lassen
     *
     * @param a
     *             Zahl vom Typ Byte,Short,Integer oder Long
     * @param b
     *             Zahl vom Typ Byte,Short,Integer oder Long
     * @return
     *             true kein Overlow trat auf
     */

    public static boolean canAdd(Number a, Number b) {

        BigInteger maxValue = null;

        if (a instanceof Byte || b instanceof Byte) {
            maxValue = BigInteger.valueOf(Byte.MAX_VALUE);
        }

        if (a instanceof Short || b instanceof Short) {
            maxValue = BigInteger.valueOf(Short.MAX_VALUE);
        }

        if (a instanceof Integer || b instanceof Integer) {
            maxValue = BigInteger.valueOf(Integer.MAX_VALUE);
        }

        if (a instanceof Long || b instanceof Long) {
            maxValue = BigInteger.valueOf(Long.MAX_VALUE);
        }
        if (maxValue == null)
            throw new IllegalArgumentException("Invalid Type");
        BigInteger aL = BigInteger.valueOf(a.longValue());
        BigInteger ab = BigInteger.valueOf(b.longValue());
        return aL.add(ab).compareTo(maxValue) <= 0;
    }
    /**
     * Wirft eine OverlowException sobald ein Overflow auftritt
     * @param a
     *             Zahl vom Typ Byte,Short,Integer oder Long
     * @param b
     *             Zahl vom Typ Byte,Short,Integer oder Long
     * @throws OverlowException
     */

    public static void checkOverflow(Number a, Number b)
            throws OverlowException {
        if (!canAdd(a, b)) {
            throw new OverlowException("a overflow occured");
        }
    }

    
    public static void main(String[] args) {
        byte a = (byte) 120;
        byte b = (byte) 30;
        byte c = (byte) 0;
        try {
            checkOverflow(a, b);
        } catch (OverlowException e) {
            System.out.println(e.getMessage());
        }
        c = (byte) (a + b); // Da du ja weißt das Byte und Byte
                                          //für Byte zu groß wird   nutze doch einfach einen Integer
               int result = (int) a+b // wäre angebrachter, verwende immer einen nächsthören
                                           // Datentyp für die Ergebnis Variable
    }
}




Du solltest Wissen, dass der Datentyp Byte in Java immer 8 Bit groß ist und signed ist.
Das 8 Bit wird für das Vorzeichen verwendet, es also sind nur 7 Bit für die Speicherung der Zahl übrig. Das sagt ein Byte kann Maximal die Werte von -128 bis 127 anehmen.
Daherführt Byte und Byte im schlechtesten Fall zu einem Overflow. Also verwender einfach einen höheren Datentyp als Byte:


C++:
byte a = (byte) 120;
byte b = (byte) 30;
int c =  0;
c = (int) a + b;



Gruß, ich hoffe ich konnte Helfen
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
29.03.2010, 20:17 Uhr
~SagIchDirNicht
Gast


Ehm sry, wieso Formatiert nicht korrekt ist [cpp] nicht das richtige Tag ?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ Java ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: