简体   繁体   中英

How to implement bitmap array in C using uint64_t data type?

I am trying to implement bitmap array in C. I've read and copy-paste from this link: What is a bitmap in C?

#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;
}

Using uint32_t, the code works well. It prints x value: 1, 3, and 7, respectively like this:

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

x=7

It doesn't work. The x value become 1295807169 etc, which was not I expected. I expect it to be the same as before (1, 3, 7). Can someone help me fix that code?

I know "<<" is bit shifting, which mean you shift the bit to the left (or adding 0 to the right). But I am still not sure how to modify the code myself.

The problem is that the code uses 1 integer constants. All such integer constants have a type just like variables and it is per default int , which is likely the same as int32_t on your system.

Left shifting a signed integer like int32_t more than 30 bits invokes undefined behavior, because you'll be shifting data into the sign bit. As a rule of thumb, never use signed variables together with bitwise operators.

The correct fix in this case is to replace every instance of 1 << BIT_OFFSET(n) with:

(word_t)1 << BIT_OFFSET(n)

Alternatively use 1ull suffix, but that may produce needlessly slow code on smaller systems.


Please note that the correct format specifier for printf is printf("x=%"PRIu64 "\\n",x); from inttypes.h.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM