Was ist falsch an diesem Bitmanipulationscode aus einer Interviewfrage?

Lesezeit: 7 Minuten

Benutzer-Avatar
Josch

Ich habe mir mal diese Seite angeschaut: http://www.devbistro.com/tech-interview-questions/Cplusplus.jspund habe diese Frage nicht verstanden:

Was ist möglicherweise falsch mit dem folgenden Code?

long value;
//some stuff
value &= 0xFFFF;

Hinweis: Geben Sie dem Kandidaten einen Hinweis auf die Basisplattform, für die er entwickelt. Wenn die Person immer noch nichts Falsches am Code findet, hat sie keine Erfahrung mit C++.

Kann jemand darauf näher eingehen?

Vielen Dank!

  • Es gibt möglicherweise eine Menge Dinge, die mit diesem Code nicht stimmen. Auf der anderen Seite könnte es gut sein. Ohne Kontext ist es unmöglich, eine vernünftige Antwort auf diese Frage zu geben.

    – James McNellis

    23. November 2010 um 1:39 Uhr


  • @James: Vielleicht bei einigen Implementierungen, vielleicht auch nicht. Das ist aber auf jeden Fall eine schreckliche Ausrede.

    – GManNickG

    23. November 2010 um 1:47 Uhr


  • Ich habe meine Antwort zur Zeichenerweiterung gelöscht, weil sie falsch ist. Ich vermute, es ist das, wonach der Interviewer sucht, aber wenn der Interviewer danach sucht, liegen sie auch falsch.

    – Allmächtig

    23. November 2010 um 2:48 Uhr

  • Man kann “erfahren in C++” sein und nie die bitweisen Operatoren verwendet haben. C++ ist eine so große Sprache, die so viele Programmierparadigmen unterstützt, dass ich nicht sicher bin, ob es möglich ist, anhand einer Frage definitiv festzustellen, ob man Erfahrung hat.

    – JohnMcG

    23. November 2010 um 3:52 Uhr

  • Axn: 0xffff Wille nicht befördert werden 0xffffffff auf jeden Fall – 0xffff ist immer gleich 65535was bedeutet, dass die Konstante einen Typ hat unsigned int wenn int ist nur 16 Bit. Es wird bleiben 0xffff / 65535 bei Beförderung zu a long.

    – Café

    23. November 2010 um 5:25 Uhr

Benutzer-Avatar
James McNellis

Mehrere Antworten hier besagen, dass wenn an int hat eine Breite von 16 Bit, 0xFFFF ist negativ. Das ist nicht wahr. 0xFFFF ist nie negativ.

Ein hexadezimales Literal wird durch den ersten der folgenden Typen dargestellt, der groß genug ist, um es aufzunehmen: int, unsigned int, longund unsigned long.

Wenn int hat dann eine Breite von 16 Bit 0xFFFF größer als der durch an darstellbare Maximalwert ist int. Daher, 0xFFFF ist vom Typ unsigned intdie garantiert groß genug ist, um sie darzustellen 0xFFFF.

Bei der Auswertung werden die üblichen arithmetischen Umrechnungen durchgeführt &das unsigned int wird in a umgewandelt long. Die Konvertierung einer 16-Bit unsigned int zu long ist wohldefiniert, da jeder Wert durch ein 16-Bit darstellbar ist unsigned int ist auch durch ein 32-Bit darstellbar long.

Es ist keine Vorzeichenerweiterung erforderlich, da der ursprüngliche Typ nicht vorzeichenbehaftet ist, und das Ergebnis der Verwendung 0xFFFF ist das gleiche wie das Ergebnis der Verwendung 0xFFFFL.

Alternativ ggf int ist dann breiter als 16 Bit 0xFFFF ist vom Typ int. Es ist eine vorzeichenbehaftete, aber positive Zahl. In diesem Fall sind beide Operanden vorzeichenbehaftet, und long den größeren Konversionsrang hat, also die int wird wieder befördert long durch die üblichen arithmetischen Umrechnungen.


Wie andere gesagt haben, sollten Sie es vermeiden, bitweise Operationen an vorzeichenbehafteten Operanden durchzuführen, da das numerische Ergebnis davon abhängt, wie die Vorzeichen dargestellt werden.

Abgesehen davon ist an diesem Code nichts Besonderes falsch. Ich würde argumentieren, dass es eine Stilfrage ist value wird nicht initialisiert, wenn es deklariert wird, aber das ist wahrscheinlich ein Kommentar auf Nit-Pick-Ebene und hängt vom Inhalt der ab //some stuff Abschnitt, der ausgelassen wurde.

Es ist wahrscheinlich auch vorzuziehen, einen Integer-Typ mit fester Breite zu verwenden (wie z uint32_t) Anstatt von long für eine größere Portabilität, aber auch das hängt von dem Code ab, den Sie schreiben, und von Ihren Grundannahmen.

  • Sie haben Recht. Ich wette, dass ein Interviewer, der diese Frage stellt, falsch liegen würde. 🙂

    – Allmächtig

    23. November 2010 um 3:00 Uhr

  • @ Omnifarious: Das ist wahrscheinlich. So oder so, ich denke, es ist eine schreckliche Interviewfrage.

    – James McNellis

    23. November 2010 um 3:06 Uhr

  • Beachten Sie jedoch, dass das numerische Ergebnis von bitweisen Operationen an vorzeichenbehafteten Operanden nur variiert, wenn negative Zahlen / das Vorzeichenbit beteiligt sind. Zum Beispiel in diesem Fall, wenn value positiv ist, dann ist das Ergebnis wohldefiniert (dasselbe wie value % 65536), doch wenn value negativ ist, dann gibt es drei mögliche Ergebnisse.

    – Café

    23. November 2010 um 5:32 Uhr

  • Aus Interesse, was sind die drei möglichen Ergebnisse caf erwähnt?

    – T .

    25. November 2010 um 16:39 Uhr

Ich denke, je nach Größe eines Long könnte das 0xffff-Literal (-1) auf eine größere Größe befördert werden, und da es sich um einen vorzeichenbehafteten Wert handelt, wird es vorzeichenerweitert und möglicherweise zu 0xffffffff (immer noch -1).

  • 0xFFFF ist nie negativ. Ich habe eine Antwort mit Details gepostet.

    – James McNellis

    23. November 2010 um 2:31 Uhr

Benutzer-Avatar
Jo

Ich nehme an, es liegt daran, dass es für long keine vordefinierte Größe gibt, außer dass es mindestens so groß sein muss wie die vorhergehende Größe (int). Abhängig von der Größe können Sie den Wert also entweder auf eine Teilmenge von Bits abschneiden (wenn long mehr als 32 Bits beträgt) oder überlaufen (wenn er weniger als 32 Bits beträgt).

Ja, Longs (gemäß der Spezifikation und danke für die Erinnerung in den Kommentaren) müssen mindestens -2147483647 bis 2147483647 (LONG_MIN und LONG_MAX) halten können.

  • Sie meinen, wenn es weniger/größer als 16 Bit ist?

    – Karl Salvia

    23. November 2010 um 1:42 Uhr

  • +1 – Ich habe nicht darüber nachgedacht, dass sich die Größe von Long ändern kann, während ich mir diese Frage ansehe.

    – Jakob Schwarz

    23. November 2010 um 1:43 Uhr

  • Ich dachte, es wäre nur int, das eine undefinierte Größe hatte, long = 32bit, long long = 64bit. Aber ferenuff, man lernt jeden Tag etwas dazu 🙂

    – dutt

    23. November 2010 um 1:45 Uhr

  • -1 A long mindestens 32 Bit garantiert, unter Bezugnahme auf den C-Standard (wo es aus dem garantierten Wertebereich folgt). Daher ist an der Aussage technisch nichts falsch. Es maskiert alle außer den unteren 16 Bits des Werts, das ist alles, und wenn das die Absicht ist (und ein Wert zugewiesen wurde), dann ist der Code richtig, und wenn das nicht die Absicht ist, dann ist der Code falsch. Der Interviewer kennt C++ nicht. Prost & hth.,

    – Prost und hth. – Alf

    23. November 2010 um 1:48 Uhr


  • @GMan Das ist wahr für int, long muss mindestens 32 Bit sein.

    – Simon Toth

    23. November 2010 um 1:59 Uhr

Da ein Wert nicht initialisiert wird, bevor das ausgeführt wird, denke ich, dass das Verhalten undefiniert ist, der Wert könnte alles sein.

Benutzer-Avatar
Julio Guerra

Die Größe des langen Typs ist plattform-/compilerspezifisch.

Was man hier sagen kann ist:

  1. Es ist unterzeichnet.
  2. Wir können das Ergebnis von value &= 0xFFFF nicht kennen; da es zum Beispiel Wert &= 0x0000FFFF sein könnte; und wird nicht das tun, was erwartet wird.

  • Wieder, long bedeutet nicht 4 Bytes. Es impliziert nur >= sizeof(int)

    – Karl Salvia

    23. November 2010 um 1:46 Uhr

  • @Billy und @Charles: Julio hat nicht vier Bytes gesagt. Er implizierte, dass die Größe von long kann sein 32 Bit (das können 1, 2 oder 4 Bytes sein, je nachdem CHAR_BIT). Und mindestens 32 Bit Größe für long wird vom Standard garantiert, es können also durchaus 32 Bit sein. Prost & hth.

    – Prost und hth. – Alf

    23. November 2010 um 2:11 Uhr


Benutzer-Avatar
mattdm

Man könnte zwar argumentieren, dass es sich um einen Pufferüberlauf oder einen anderen Fehler handelt, der wahrscheinlich ausgenutzt werden kann Stil Ding und kein Fehler, bin ich zu 99% zuversichtlich, dass die Antwort, nach der der Fragesteller sucht, diese ist value operiert wird, bevor es zugewiesen wird. Der Wert wird willkürlicher Müll sein, und es ist unwahrscheinlich, dass das gemeint war, also ist er “potenziell falsch”.

  • Wieder, long bedeutet nicht 4 Bytes. Es impliziert nur >= sizeof(int)

    – Karl Salvia

    23. November 2010 um 1:46 Uhr

  • @Billy und @Charles: Julio hat nicht vier Bytes gesagt. Er implizierte, dass die Größe von long kann sein 32 Bit (das können 1, 2 oder 4 Bytes sein, je nachdem CHAR_BIT). Und mindestens 32 Bit Größe für long wird vom Standard garantiert, es können also durchaus 32 Bit sein. Prost & hth.

    – Prost und hth. – Alf

    23. November 2010 um 2:11 Uhr


Benutzer-Avatar
figurieren

Bei Verwendung von MSVC denke ich, dass die Anweisung das ausführen würde, was höchstwahrscheinlich beabsichtigt war – das heißt: alle bis auf die niedrigstwertigen 16 Bits des Werts löschen, aber ich bin auf andere Plattformen gestoßen, die das Literal 0xffff als äquivalent zu (short) -1 interpretieren würden. then sign extend zur Umwandlung in long, in diesem Fall hätte die Anweisung “value &= 0xFFFF” keine Wirkung. “value &= 0x0FFFF” ist expliziter und robuster.

1351360cookie-checkWas ist falsch an diesem Bitmanipulationscode aus einer Interviewfrage?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy