Binary to decimal

I have a 4 byte unsigned char.  I am taking the 1st byte, and extracting bits 29 through 27 as well as 13 and 11.
I need to then take each set of 3 bits and get the decimal value of it.

Is there a graceful way of doing this other than extracting each bit manually then calculating the decimal value?
jeweeAsked:
Who is Participating?
 
jkrCommented:
Actually that's easy, that's what a binary '&' is for

#define EXTRACT_MASK (1 << 29) | (1 << 28) | (1 << 27) | (1 << 13) | (1 << 11)

unsigned char uc[4];
unsigned long ul = *(unsigned long*) uc;

unsigned long result = ul & EXTRACT_MASK;

printf("Result: %u\n", result)
0
 
srinimsCommented:
for>>
>>I need to then take each set of 3 bits and get the decimal value of it.

#define EXTRACT_MASK1 (1 << 29) | (1 << 28) //having bit value 1 at position 29 and 28, and other places filled 0's
#define EXTRACT_MASK2 (1 << 27) | (1 << 13) | (1 << 11)

unsigned char uc[4];
unsigned long ul = *(unsigned long*) uc;

printf("Result: %u %u\n", (ul & EXTRACT_MASK1), (ul & EXTRACT_MASK2))
0
 
Dragon_KromeCommented:
The solutions given above won't give you the actual decimal value of the 3 bits, but the result of AND-ing the extraction masks with the initial number. The results need to be right shifted for this to be accurate.
You said 13 and 11 and then you mention "each set of 3 bits", so i assume you meant 13 to 11 too.

Here's a modified solution based on jkr's:

#define EXTRACT_MASK (7 << 11)|(7<<27)

unsigned char uc[4];
unsigned long ul = *(unsigned long*) uc;

unsigned long result = ul & EXTRACT_MASK;

unsigned char group_11_13 = (result >> 11) & 7;
unsigned char group_27_29 = (result >> 27) & 7;

printf("%u %u", group_11_13, group_27_29);



0
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

 
Infinity08Commented:
It's still not what jewee is looking for i think (correct me if I'm wrong). Here's my attempt :

#define EXTRACT_1(ul) (((ul) & 0x38000000) >> 27)
#define EXTRACT_2(ul) (((ul) & 0x00003800) >> 11)

unsigned char uc[4];
unsigned long ul = *(unsigned long*) uc;

printf("Result: %u %u\n", EXTRACT_1(ul), EXTRACT_2(ul))
0
 
Infinity08Commented:
Dragon_Krome posted the same time as me - his solution should work too, although a bit more complicated.
0
 
kaliyugkaarjunCommented:


Hi jewee , chk out this code ..enter any binay no. and u will get its decimal, hexadecimal  as well as octal representation..
cheers.

prog starts below
//-----------------
#include <stdio.h>
#include <string.h>
 
int bin2dec(char *bin);
 
int main()
{
  char bin[80] = "";
  char *p;
  int  dec;
 
  while(strcmp(bin,"0"))
  {
    printf("\n Enter a binary number (just 0 to EXIT): ");
    fgets(bin, sizeof(bin), stdin);
    // check for and remove trailing \n
    if ((p = strchr(bin,'\n')) != NULL)
    {
      *p = '\0';
    }
    dec = bin2dec(bin);
    if (dec) printf("\nDecimal = %d  Hexadecimal = 0x%04X  Octal = 0%o\n",dec,dec,dec);
  }
 
  getchar();  // wait
  return 0;
}
 
// convert a binary string to a decimal number, returns decimal value
int bin2dec(char *bin)  
{
  int  b, k, m, n;
  int  len, sum = 0;
 
  len = strlen(bin) - 1;
  for(k = 0; k <= len; k++)
  {
    n = (bin[k] - '0'); // char to numeric value
    if ((n > 1) || (n < 0))
    {
      puts("\n\n ERROR! BINARY has only 1 and 0!\n");
      return (0);
    }
    for(b = 1, m = len; m > k; m--)
    {
      // 1 2 4 8 16 32 64 ... place-values, reversed here
      b *= 2;
    }
    // sum it up
    sum = sum + n * b;
    //printf("%d*%d + ",n,b);  // uncomment to show the way this works
  }
  return(sum);
}
0
 
padamjsCommented:
This is a very simple way of extracting the decimal value of bits 29-27 and 13-11 stored in the unsignied char bytes:

unsigned char data[4];

///fill value in this char data

dec1=(data[0] & 0x1c)>>2;
dec2=(data[2] & 0x1c)>>2;

In binary, 0x1c is 001 1100.  So for the first byte, this mask will get you bits in positions 29-27 and in the third byte, it will get you bits 13-11.
The "shift right" two bits to get the decimal value.

HTH.
Padam JS.
0
 
Infinity08Commented:
>> In binary, 0x1c is 001 1100
Bit counting starts from 0, so you need 0x38 (and a shift of 3) as in my earlier example.
0
 
padamjsCommented:
>>Bit counting starts from 0, so you need 0x38 (and a shift of 3) as in my earlier example.
Bit counting indeed starts at 0.
However, 0x1c>>2 is equal to 0x38>>3!
Also, you are generating a mask with 0x38, which very well can be done using 0x1c.

I am not generating any mask, and hence I can just And with the mask 0x1c.
0
 
Infinity08Commented:
My point was that you're extracting the wrong bits :

    dec1=(data[0] & 0x1c)>>2;

will extract bits 28-26 and not 29-27 as requested.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.