2017-12-12 5 views
0

Ich versuche, Bitmap-Array in C Ich habe gelesen, zu implementieren und Copy-Paste von diesem Link: What is a bitmap in C?Wie implementiert man ein Bitmap-Array in C mit dem Datentyp uint64_t?

#include <limits.h> /* for CHAR_BIT */ 
#include <stdint.h> /* for uint32_t */ 
#include <stdio.h> 
#include <stdlib.h> 

typedef uint32_t word_t; // I want to change this, from uint32_t to uint64_t 
enum { BITS_PER_WORD = sizeof(word_t) * CHAR_BIT }; 
#define WORD_OFFSET(b) ((b)/BITS_PER_WORD) 
#define BIT_OFFSET(b) ((b) % BITS_PER_WORD) 

void set_bit(word_t *words, int n) { 
    words[WORD_OFFSET(n)] |= (1 << BIT_OFFSET(n)); 
} 

void clear_bit(word_t *words, int n) { 
    words[WORD_OFFSET(n)] &= ~(1 << BIT_OFFSET(n)); 
} 

int get_bit(word_t *words, int n) { 
    word_t bit = words[WORD_OFFSET(n)] & (1 << BIT_OFFSET(n)); 
    return bit != 0; 
} 

int main(){ 
    printf("sizeof(word_t)=%i\n",sizeof(word_t)); 
    printf("CHAR_BIT=%i\n",CHAR_BIT); 
    printf("BITS_PER_WORD=%i\n",BITS_PER_WORD); 
    word_t x; 

    set_bit(&x, 0); 
    printf("x=%u\n",x); 
    set_bit(&x, 1); 
    printf("x=%u\n",x); 
    set_bit(&x, 2); 
    printf("x=%u\n",x); 

    return 0; 
} 

uint32_t verwenden, funktioniert der Code gut. Er druckt x-Wert: 1, 3 und 7 jeweils wie folgt aus:

[[email protected] latihan]$ ./a.out 
sizeof(word_t)=8 
CHAR_BIT=8 
BITS_PER_WORD=64 
x=1 
x=3 

x = 7

Es funktioniert nicht. Der x-Wert wird 1295807169 usw., was ich nicht erwartet habe. Ich erwarte, dass es so ist wie zuvor (1, 3, 7). Kann mir jemand helfen, diesen Code zu reparieren?

Ich weiß "< <" ist Bitverschiebung, was bedeutet, dass Sie das Bit nach links verschieben (oder 0 nach rechts hinzufügen). Aber ich bin mir noch nicht sicher, wie ich den Code selbst modifizieren soll.

+0

Können Sie bitte Ihre Frage bearbeiten, um uns die tatsächliche Ausgabe Ihres Programms sowie die erwartete Ausgabe zu zeigen. Auch beim Umgang mit Bits ist es oft sinnvoller, Zahlen stattdessen hexadezimal zu drucken (einfacher zu erkennen, welche Bits gesetzt sind oder nicht). –

+3

Es ist ein Schuss in blau, aber '1' ist eine 'int'-Konstante. Ein Cast könnte helfen, z. B .: '(word_t) 1'. Andernfalls könnten Teile Ihrer Berechnung in 'int' und Teile mit' uint64_t' erfolgen und dies könnte Nebenwirkungen haben. – Scheff

+1

Ich schlage vor, dass Sie Bit-Werte in Hex ausgeben, die Ihnen eine viel bessere Vorstellung davon geben sollten, was vor sich geht. benutze% x mit deinen printf-Aufrufen (auch – SoronelHaetir

Antwort

1

Das Problem ist, dass der Code 1 Integer-Konstanten verwendet. Alle solche Integer-Konstanten haben einen Typ wie Variablen und ist standardmäßig int, was wahrscheinlich dasselbe ist wie int32_t auf Ihrem System.

Linke Verschiebung einer vorzeichenbehafteten Ganzzahl wie int32_t mit mehr als 30 Bit ruft ein undefiniertes Verhalten auf, da Sie Daten in das Vorzeichenbit verschieben. Als Faustregel sollten Sie niemals signierte Variablen zusammen mit bitweisen Operatoren verwenden.

Die richtige Lösung besteht in diesem Fall ist jede Instanz 1 << BIT_OFFSET(n) mit ersetzen:

(word_t)1 << BIT_OFFSET(n) 

Alternativ verwenden 1ull Suffix, aber das kann entstehen unnötig langsam Code auf kleineren Systemen.


Bitte beachten Sie, dass die richtige Formatangabe für printf printf("x=%"PRIu64 "\n",x); von inttypes.h ist.

Verwandte Themen