Was ist der portabelste Weg, das höchste Bit einer ganzen Zahl in GNU C zu erhalten / setzen?
Dies ist eine Bloomberg-Interviewfrage. Ich habe zu dieser Zeit keine beste Antwort gegeben. Jeder kann es beantworten?
Danke
Wenn der Typ unsigniert ist, ist es einfach:
%Vor%Für vorzeichenbehaftete Werte kenne ich keinen Weg. Wenn Sie einen Weg finden, würde es mehrere unbeantwortete Fragen zu SO beantworten:
C Frage: off_t (und andere vorzeichenbehaftete Integer-Typen) minimale und maximale Werte
Gibt es eine Möglichkeit, die Breite eines Integer-Typs zur Kompilierzeit zu berechnen?
Vielleicht andere.
Beachten Sie zuerst, dass es keinen portablen Weg gibt, um auf das oberste Bit zuzugreifen, wenn wir über vorzeichenbehaftete Ganzzahlen sprechen; Es gibt einfach keine einzige tragbare Repräsentation, die im Standard definiert ist, daher kann die Bedeutung von "Top-Bit" im Prinzip variieren. Außerdem erlaubt C keinen direkten Zugriff auf die bitweise Darstellung; Sie können auf das int als char
-Puffer zugreifen, aber Sie haben keine Ahnung, wo sich das 'oberste Bit' befindet.
Wenn es nur um den nicht-negativen Bereich einer vorzeichenbehafteten Ganzzahl geht und angenommen wird, dass der Bereich eine Größe von zwei Potenzgrößen hat (falls nicht, dann müssen wir uns wieder um die vorzeichenbehaftete Darstellung kümmern):
%Vor%Ein ähnlicher Ansatz kann mit unsignierten Ints verwendet werden, wo er verwendet werden kann, um das wahre obere Bit zu erhalten.
Hier ist ein dummer, mit:
%Vor%Erster Versuch:
%Vor% Hinweis: Es ist eine Eigenart von C, dass Funktionen, die die Parameter int
oder unsigned int
angeben, mit dem anderen Typ ohne Warnung aufgerufen werden können. Aber das beinhaltet wahrscheinlich eine Konvertierung - der C ++ Standard 4.7.2 sagt:
Wenn der Zieltyp nicht vorzeichenbehaftet ist, ist der resultierende Wert die am wenigsten vorzeichenlose Ganzzahl, die deckungsgleich zur Quell-Ganzzahl ist (Modulo 2n, wobei n die Anzahl der Bits ist, die zur Darstellung des Typs ohne Vorzeichen verwendet werden). [Anmerkung: In einer Zweierkomplementdarstellung ist diese Umwandlung konzeptionell und es gibt keine Änderung im Bitmuster (wenn keine Kürzung erfolgt). ]
Dies impliziert, dass das Bitmuster geändert werden kann, wenn es keine Zweierkomplementdarstellung ist, was verhindern würde, dass diese "Lösung" auch zuverlässig arbeitet. : - (
Der folgende Kommentar von Chris bietet eine Lösung (die hier als Funktion und nicht als Präprozessormakro enthalten ist):
%Vor%Tags und Links c bitwise-operators