Derek Springer
Derek Springer

Reputation: 2716

What is an efficient method to determine the size of a type given as a binary string?

First off, lets assume I have endian sorted out and know the size of the types a priori.

Here's what I am doing: I have a function bs2i(char *bitStr) that takes in a character array representing the binary of a signed char/short/int/long. The array can be of any length <= sizeof(long long).

What I want to do is take bitStr[0] and set it as the sign bit such that it won't be truncated if I do something like char val = bs2i("111"). In this case, the function should return -125, as the bits would be set as "000...00010000011." To do this, I need to know how long the final type needs to be so I can shift the msb to the proper spot.

This is what I have thus far:

size_t size = (((strlen(bitStr)-1)>>3)+1)<<3;

But I just realized that only works for chars and shorts. For instance, a string of length 17 should return size 32, but would only return 24 with this method. Is there an efficient way to determine what the proper length should be?

For reference, here is the full function:

long long bs2i(char *bitStr) {
    long long val = 0l;
    size_t len = (((strlen(bitStr) - 1) >> 3) + 1) << 3;
    char msb = *bitStr & 1;
    bitStr++;
    while (*bitStr) {
        val = (val << 1l) | (*bitStr & 1);
        bitStr++;
    }
    val = (msb << len-1l) | val; /* Use MSB as sign bit */

    return val;
}

Bonus points, I guess, if there's a good way to do this that doesn't require a priori knowledge of type sizes.

Upvotes: 3

Views: 168

Answers (2)

MSN
MSN

Reputation: 54604

You want to round up the bit length to a power of two with a minimum of 8. Wikipedia has a decent algorithm for doing this. The essence of the algorithm is to set every bit below the highest bit, then add one.

You'll have to adjust it slightly since you don't want to round 8 to 16, but that's simple enough to figure out on your own.

Upvotes: 0

Dmitri
Dmitri

Reputation: 9375

It sounds like you want to find the smallest power-of-two, multiple of 8 number of bits that would fit as many bits as there are characters in the string. If you have a maximum of 64 bits, why not just use a switch on the string length?

switch((strlen(bitStr) - 1) >> 3) {
  case 0: return 8;  /* strlen <= 8 */
  case 1: return 16; /* strlen <= 16 */
  case 2:
  case 3: return 32; /* strlen <= 32 */
  case 4:
  case 5:
  case 6:
  case 7: return 64; /* strlen <= 64 */
  default: return 0;
}

Alternatively, you could try this:

int reqIntSz(char *bitStr)
{
  int len = strlen(bitStr);
  int res = 8;
  while ( len > res ) res <<= 1;
  return res;
}

Upvotes: 4

Related Questions