Unsigned
-
123 schrieb:
Konrad Rudolph schrieb:
So, bisher hat aber immernoch niemand in diesem Thread die Anfangsfrage beantwortet, nämlich, wofür 'unsigned' denn nun gut ist. Ich bitte darum, das noch zu tun, die Antwort würde mich nämlich auch interessieren. Bisher kenne ich keinen guten Grund für 'unsigned'.
Nimm mal was einfaches z.B. einen Dateizeiger, warum sollte der signed sein?
Warum nicht? Es handelt sich eh um eine schlechte Approximation. Meiner Meinung hat man hier mehrere Möglichkeiten der Darstellung, je nach Grad der Abstraktion: man kann ein 'int' nehmen -- oder ein 'FilePointer'. Klar, 'unsigned int' wäre auch eine Möglichkeit, ist IMHO aber unnötig. Man sollte eh die beste Möglichkeit nehmen, also 'FilePointer'.
-
Nachtrag: Mir ist natürlich klar, dass die Prozessorarchitektur nunmal vorzeichenlose Typen zur Verfügung stellt. Wenn man also auf Maschinenebene argumentiert, kann man durchaus 'unsigned int' verwenden. Generell programmiert man ja aber auf einer viel höheren Abstraktionsebene.
-
Was geht schneller bei einem Vergleich "<" ?
-
Wieviel Speicher kann man mit signed addressieren und wieviel mit unsigned?
-
THX 1138 schrieb:
Was geht schneller bei einem Vergleich "<" ?
Sollte gleichschnell sein, wenn ich mich nicht irre. Meiner Meinung nach wird in beiden Fällen dieselbe Anzahl an Gattern benötigt, nur dass das erste Gatter jeweils umgekehrte Eingänge besitzt.
-
Apollon schrieb:
Wieviel Speicher kann man mit signed addressieren und wieviel mit unsigned?
Hmm. Ist das heutzutage relevant? Wenn der Speicher von 'int' nicht recht nimmt man halt die nächstgrößere Einheit. Dafür ein 'unsigned int' zu verwenden finde ich popelig, denn früher oder später wird man auch damit Probleme haben, man hat das Problem in guter Politiker-Manier also nicht gelöst sondern nur verschoben.
-
Zum logischen Shiften braucht man z.B. unsigned Datentypen und die ganze
Bit-Logig hat mit dem Vorzeichen-Bit auch nichts am Hut.
-
123 schrieb:
Zum logischen Shiften braucht man z.B. unsigned Datentypen und die ganze
Bit-Logig hat mit dem Vorzeichen-Bit auch nichts am Hut.Was hat das Vorzeichenbit mit Bit-Logik zu tun? Bei mir klappt das alles wunderbar, egal ob mit oder ohne Vorzeichen.
Zum logischen Shift: Wieso? Abgesehen davon implementiert C++ doch eh nur arithmetisches Bitschieben.
-
Das rechtsschieben von negativen Integern ist nicht festgelegt. Es kann logisch oder arithmetisch geshiftet werden.
-
TactX schrieb:
Das rechtsschieben von negativen Integern ist nicht festgelegt.
Das ist mir klar, hat aber mit der Problematik nichts zu tun.
Es kann logisch oder arithmetisch geshiftet werden.
Stimmt, mein Fehler. Logisches Schieben klappt trotzdem mit 'signed int'.
-
TactX schrieb:
Das rechtsschieben von negativen Integern ist nicht festgelegt. Es kann logisch oder arithmetisch geshiftet werden.
int a = 0xffffffff; a >>= 30; // Ergebnis: a == -1 // erlaubt oder nicht? (arithmetischer Shift mit richtigem Ergebnis) unsigned int b = 0xffffffff; // logischer Shift b >>= 30; // Ergebnis: b == 3
-
für alles was sich besser mit 'natürlichen zahlen' darstellen darstellen lässt, nimmt man lieber 'unsigned'. beispiel:
int wie_weit_komme_ich (int liter_benzin_im_tank) { if (liter_benzin_im_tank > 30) /* fehleingabe: zu viel */ return -1; if (liter_benzin_im_tank < 0) /* fehleingabe: zu wenig */ return -1; ... ... }die zweite überprüfung wäre bei 'unsigned' nicht nötig...

-
ten schrieb:
für alles was sich besser mit 'natürlichen zahlen' darstellen darstellen lässt, nimmt man lieber 'unsigned'.
Genau das überzeugt mich ja gerade nicht. Man spart in Deinem Beispiel zwar eine triviale Abfrage, trotzdem könnte man die Funktion aber falsch aufrufen:
wie_weit_komme_ich(-1);Das eigentliche Problem hier (Modellieren einer natürlichen Zahl) hat man nicht gelöst, man hat lediglich zwei Codezeilen gespart.
-
Konrad Rudolph schrieb:
Genau das überzeugt mich ja gerade nicht. Man spart in Deinem Beispiel zwar eine triviale Abfrage
die abfrage ist zwar trivial, aber wehe, wenn man sie vergisst einzubauen.
...und falls sich so'ne funktion in einem zeitkritisschen code befindet, ist es auch besser, weniger abfragen zu haben.
und was ist mit dem wertebereich? stell dir vor (auf einem 16 bit system), brauchst du eine funktion, die werte zwischen 0 und 40000 annehmen darf. würdest du dafür lieber den nächsthöheren datentyp, also 'long' statt eines 'unsigned int' nehmen und damit geschwindigkeitseinbussen riskieren?
-
Konrad Rudolph schrieb:
TactX schrieb:
Das rechtsschieben von negativen Integern ist nicht festgelegt.
Das ist mir klar, hat aber mit der Problematik nichts zu tun.
Doch, hat es. Und zwar genau deswegen. Das Shiften von negativen Werten ist implementationsspezifisch. Daher weisst du nicht, wie ein Compiler hier shiftet. Wenn man auf Bitebene arbeitet, braucht man aber zuverlässige Ergebnisse. Was anderes wäre es, wenn C++ festlegen würde, dass generell logisch geshiftet wird. Warum das nicht gemacht wurde, da fragst du am besten mal beim ISO Komitee nach.
Konrad Rudolph schrieb:
ten schrieb:
für alles was sich besser mit 'natürlichen zahlen' darstellen darstellen lässt, nimmt man lieber 'unsigned'.
Genau das überzeugt mich ja gerade nicht. Man spart in Deinem Beispiel zwar eine triviale Abfrage, trotzdem könnte man die Funktion aber falsch aufrufen:
wie_weit_komme_ich(-1);Das eigentliche Problem hier (Modellieren einer natürlichen Zahl) hat man nicht gelöst, man hat lediglich zwei Codezeilen gespart.
Was man jedoch gerne mitnimmt. Jede Vereinfachung ist willkommen. Und für dich mag das zwar trivial erscheinen. Aber gerade Sprunganweisungen, die in kurzen Sequenzen sehr häufig abgearbeitet werden, können ordentlich auf die Performance drücken. Zudem ist es einfach sauberer. Wenn ein negativer Wert nicht plausibel ist, dann soll auch keiner im verwendeten Typ gespeichert werden können. Übrigens, ein Compiler mit pedantischer Fehlerprüfung sollte hier zumindest eine Warnung ausspucken. GCC macht das zB mittels -Wconversion.
Wenn überhaupt, dann stellt sich die Frage in C++ nicht nach dem unsigned. Sondern warum man eine explizite Aufteilung in signed und unsigned Typen macht.
-
groovemaster schrieb:
Wenn überhaupt, dann stellt sich die Frage in C++ nicht nach dem unsigned. Sondern warum man eine explizite Aufteilung in signed und unsigned Typen macht.
Ja, so meinte ich das eigentlich auch.
Wobei ich die Antworten in dem Thread schon ganz gut finde.
-
Konrad Rudolph schrieb:
So, bisher hat aber immernoch niemand in diesem Thread die Anfangsfrage beantwortet, nämlich, wofür 'unsigned' denn nun gut ist. Ich bitte darum, das noch zu tun, die Antwort würde mich nämlich auch interessieren. Bisher kenne ich keinen guten Grund für 'unsigned'.
Es gibt mehrere Gründe
a) Die Ausdrucksstärke des Codes wird erhöht
b) Überlauf bei Signed-Variablen ist undefiniert
c) Zahlreiche potentielle Probleme und Sicherheitslücken
(wer sieht den Fehler?)void foo(int n) { char buffer[SIZE]; // ... if(abs(n) >= SIZE) throw out_of_range(); do_sth(buffer[abs(n)]); }d) ...
(oder sagen wir mal, die Fragestellung muss man andersrum angehen: "Warum sollte man auf unsigned verzichten?")
-
rüdiger schrieb:
(oder sagen wir mal, die Fragestellung muss man andersrum angehen: "Warum sollte man auf unsigned verzichten?")
Was mich eher interessieren würde:
Sollten unsigned-Datentypen fester Bestandteil einer (neuen) modernen, effizienten Programmiersprache sein (außer für Interop-Zwecke)?
Bisher dachte ich, die Antwort darauf laute "nein", so langsam lasse ich mich aber gerade vom Gegenteil überzeugen.
-
rüdiger schrieb:
(wer sieht den Fehler?)
if(abs(n) >= SIZE) ...müsste sein:
if(abs(n) > SIZE)hat aber mit dem eigentlichen thema hier nix zu tun...

-
ten schrieb:
rüdiger schrieb:
(wer sieht den Fehler?)
if(abs(n) >= SIZE) ...müsste sein:
if(abs(n) > SIZE)hat aber mit dem eigentlichen thema hier nix zu tun...

ne
int a[5]; a[5]=10; // <-- das wäre ja auch ein Overflow