-3

I have a byte array represented as

char * bytes = getbytes(object); //some api function

I want to check whether the bit at some position x is set.

I've been trying this

int mask = 1 << x % 8;
y= bytes[x>>3] & mask;

However y returns as all zeros? What am I doing incorrectly and is there an easier way to check if a bit is set?

EDIT:

I did run this as well. It didn't return with the expected result either.

  int k = x >> 3;
   int mask = x % 8;
    unsigned char byte = bytes[k];
   return (byte & mask);

it failed an assert true ctest I ran. Byte and Mask at this time where "0002" and 2 respectively when printed from gdb.

edit 2: This is how I set the bits in the first place. I'm just trying to write a test to verify they are set.

unsigned long x = somehash(void* a);

unsigned int mask = 1 << (x % 8);

unsigned int location = x >> 3;
char* filter = getData(ref);

filter[location] |= mask;
knowads
  • 705
  • 2
  • 7
  • 24
  • 1
    Parentheses `()`are your friend. – Yunnosch Jul 04 '17 at 04:35
  • The expression looks fine to me. What is the type of `y`? Does `bytes` point to consecutive memory region of `char`s? – nglee Jul 04 '17 at 04:58
  • One possible source of confusion is bit-endianness. As is, your code interprets `x = 0` as the least significant bit of the first byte. – user3386109 Jul 04 '17 at 04:58
  • Please provide sample input and expected output. – Yunnosch Jul 04 '17 at 05:00
  • Print everything separatly for debugging, especially `bytes[x>>3]`. – Yunnosch Jul 04 '17 at 05:06
  • 1
    In short, please make a [mcve]. – Yunnosch Jul 04 '17 at 05:06
  • @nglee y is in the official code listed as a bool which is just an int typedef – knowads Jul 04 '17 at 05:12
  • Have you given any thought to complications that will arise from `y= bytes[x>>3] & mask;`, e.g. `y = char & int`? (one byte anded against four). Perhaps using `uint8_t` for all would help? – David C. Rankin Jul 04 '17 at 05:18
  • @DavidC.Rankin this is how I set the code in the first place: I'm just trying to write something to verify it. I just need something that returns a 1 if that bit is set. unsigned int mask = 1 << (x % 8); unsigned int location = x >> 3; char* filter = getData(ref); filter[location] |= mask; – knowads Jul 04 '17 at 05:20
  • Recall if your system is *little-endian* the least significant bits of an `int` are 3-bytes to the left... – David C. Rankin Jul 04 '17 at 05:21

1 Answers1

0

This would be one (crude perhaps) way from the top of my head:

#include "stdio.h"
#include "stdlib.h"

// this function *changes* the byte array
int getBit(char *b, int bit)
{
  int bitToCheck = bit % 8;
  b = b + (bitToCheck ? (bit / 8) : (bit / 8 - 1));

  if (bitToCheck)
    *b = (*b) >> (8 - bitToCheck);

  return (*b) & 1;
}

int main(void)
{
  char *bytes = calloc(2, 1);
  *(bytes + 1)= 5;  // writing to the appropiate bits
  printf("%d\n", getBit(bytes, 16)); // checking the 16th bit from the left
  return 0;
}

Assumptions:

A byte is represented as:

----------------------------------------
| 2^7 | 2^6 | 2^5 | 2^4 | 2^3 |...     |
----------------------------------------

The left most bit is considered bit number 1 and the right most bit is considered the max. numbered bit (16th bit in a 2 byte object).

It's OK to overwrite the actual byte object (if this is not wanted, use memcpy).

babon
  • 3,615
  • 2
  • 20
  • 20
  • I think you have to consider the endiannes of the system like [here](https://stackoverflow.com/a/4181991/8051589), because you have multiple bytes in an array. – Andre Kampling Jul 04 '17 at 06:11
  • You guys know what. I think it might be something to do with the bool typedef and the api I was using to retrieve the byte. I made everything vanilla ints and it seemed to run as expected. I'm going to look into it further and discuss with the original author – knowads Jul 04 '17 at 06:25
  • @AndreKampling Ahhh... you just had to make this difficult for me ;P – babon Jul 04 '17 at 06:27
  • @knowads 'much ado about nothing'? – babon Jul 04 '17 at 06:27
  • @babon I guess so. I'm still green enough to not realize that I can be completely correct but something can go wrong because of an implementation decision in someone's original API not accounting for certain use cases – knowads Jul 04 '17 at 06:29
  • @knowads no problem, carry on :) – babon Jul 04 '17 at 06:33