Endian - Vorzeichen ermitteln
-
Hallo,
ich suche nach einer eleganten Möglichkeit, das Vorzeichen einer Zahl zu ermitteln. Im Endian-Header <endian.h> (Linux) erfahre ich mehr über das verwendete System.
Aber, wie bekomme ich das Vorzeichen einer Zahl?
int i; if(i < 0) .... // Naja, elegant ist das nichtWie sieht die Maske für das Abschneiden des Vorzeichen mittels & für Big-Endian aus?
Oder hat der GCC bzw. C++ Standard bereits Methoden hinterlegt?Gruß
Thomas
-
Ist es etwa eleganter eine kilometerlange Funktion dafür aufzurufen?
Also ich glaube kaum, dass es dafür extra eine Funktion gibt und unelegant finde ich die Lösung mit if auch nicht unbedingt. Bei Google hab ich auf die schnelle auch nichts gefunden.
-
Naja, ich möchte das Rad nicht neu erfinden. Leider kenne ich die gesamte Lib. nicht auswendig. Ich meine, dass es da was gibt. Big und liitle gibt es ja nicht seit gestern.
Methoden aufrufe bzw. Makros stören mich nicht. Leserlichkeit und Sauberkeit stehen an erster Stelle. Denn Rest muss der Compiler erledigen.
-
Gibt es etwas sauberes als x<0?
Hier, sogar als Funktion:
bool isNegative(int x) { return x<0; }Außerdem ist meiner Meinung nach das Abschneiden des Vorzeichens wesentlich uneleganter. (und mit ziemlicher Sicherheit sogar langsamer)
-
Siassei schrieb:
ich suche nach einer eleganten Möglichkeit, das Vorzeichen einer Zahl zu ermitteln. [...]
Was meinst Du mit "ermitteln"? Was ist denn die gewünschte Ausgabe? Wozu brauchst Du das Vorzeichen? Also, was willst Du damit machen?
Siassei schrieb:
Aber, wie bekomme ich das Vorzeichen einer Zahl?
int i; if(i < 0) .... // Naja, elegant ist das nichtNicht?! Das kann man nicht so richtig beurteilen. Ich behaupte mal, es hängt davon ab, was Du damit machen willst. Für bestimmte Dinge gibt es ein paar Tricks, mit denen man sich Verzweigungen (if else) sparen kann. Verzweigungen mögen CPUs nicht so gerne. Man kann aber eigentlich davon ausgehen, dass
bool neg = i<0;von einem guten Compiler sehr effizient übersetzt wird. Mein G++ macht daraus für meine Intel-CPU folgende Assembler-Zeile
shr $0x1f,%eaxEr shiftet also die Zahl im Register EAX um 31 Bits nach rechts, was nur das Vorzeichenbit übrig lässt, weil EAX ein 32Bit Register ist und Intel-CPUs 2er-Komplement für vorzeichenbehaftete Zahlen nutzen.
Siassei schrieb:
Wie sieht die Maske für das Abschneiden des Vorzeichen mittels & für Big-Endian aus? Oder hat der GCC bzw. C++ Standard bereits Methoden hinterlegt?
1. Endianness interessiert hier gar nicht, wenn Du nicht per char* oder unsigned char* auf den int zugreifst.
2. Die Binärdarstellung vorzeichenbehafteter Zahlen wird nicht vom C oder C++ Standard festgelegt. In Frage kommen 1er-Komplement, 2er-Komplement und Vorzeichen+Betrag. Das Verhalten der Operatoren &, |, ^, ~ auf vorzeichenbehaftete Operanden ist also abhängig von Deinem Compiler bzw Deinem Rechner. Du kannst aber einen "signed int s" zu einem "unsigned int u" konvertieren. Diese Konvertierung ist wohldefiniert. Es gilt s = u mod 2^N, wobei N die Anzahl der Bits sind, die für int benutzt werden.Gruß,
SP
-
Servus,
im Assembler habe ich noch gar nicht nachgeschaut. Upps

Was möchte ich machen. Hmmm, ich habe vor ein paar Jahre eine kleine Bibliotheke in Java geschrieben und jetzt muss ich diese nach C++ konvertieren. Grund für die Umstellung ist die Schnittstelle, nicht die Gerüchteküche von Java! Ich liebe es, aber das ist Off-Topic!
Die Algorithmen sind des öfteren komplett in Bit-Operationen umgesetzt und muss daher auf die Endian-Geschichte achten (versch. Plattformen). Ich möchte nicht alles doppelt und dreifach tippen und dabei die Reihenfolge und Co verändern. Daher suche ich nach einer Abfolge bzw. kleine Helferlein die mir das Leben erleichtern.
Da heißt es wohl selbst hand anlegen. Ich wandle jetzt alle Integer's mittels den Makros aus <endian.h> in Little-Endian um. Für spätere Operation z.B. + oder Darstellung in einer Textbox erfolgt eine erneute Wandlung. Die schönste Lösung meiner seits.
Gruß
Thomas
-
ist es denn wirklich nötig, das so maschienen-nah zu machen? oder vermutest du nur, dass es dadurch schneller werden könnte?
falls ja: ich würd auf den compiler wetten
bb
-
Ja, da es sich um Array's handelt.
-
Siassei schrieb:
Ja, da es sich um Array's handelt.
versteh ich nicht - falls ichs doch verstanden habe, dann hast du mich wohl nicht verstanden ;o)
mach doch ma nen bsp., was deine bibliothek berechnen kann und wie du es implementiert hast - dann schreib ichs mal in C++ und wir gucken, wie viel schneller deins ist (und ob überhaupt)...
bb
-
Siassei schrieb:
Was möchte ich machen. Hmmm, ich habe vor ein paar Jahre eine kleine Bibliotheke in Java geschrieben und jetzt muss ich diese nach C++ konvertieren.
[...]
Die Algorithmen sind des öfteren komplett in Bit-Operationen umgesetzt und muss daher auf die Endian-Geschichte achten (versch. Plattformen).Blödsinn. In Java hast Du gar nicht die Möglichkeit, herauszufinden, wie ints im Speicher abgelegt werden. Wenn Du Deinen Java-Code nach C++ übersetzt, spielt Endianness genausowenig eine Rolle. Erst wenn Du auf Deine Ints byte-weise zugreifst macht das einen Unterschied. Aber wie gesagt, das geht ja in Java sowieso nicht. Und warum solltest Du Dir es in C++ unnötig kompliziert machen?
Siassei schrieb:
Ich möchte nicht alles doppelt und dreifach tippen und dabei die Reihenfolge und Co verändern.
Musst Du ja auch nicht. Mach's doch genauso wie in Java.
Siassei schrieb:
Daher suche ich nach einer Abfolge bzw. kleine Helferlein die mir das Leben erleichtern.
bla, bla, bla. Gib doch mal'n Beispiel.
Siassei schrieb:
Da heißt es wohl selbst hand anlegen.
Nicht wirklich.
Siassei schrieb:
Ich wandle jetzt alle Integer's mittels den Makros aus <endian.h> in Little-Endian um. Für spätere Operation z.B. + oder Darstellung in einer Textbox erfolgt eine erneute Wandlung. Die schönste Lösung meiner seits.

So ein Blödsinn. Du denkst viel zu kompliziert.Gruß,
SP