views:

100

answers:

5

I am writing a program that needs to take an array of size n and convert that into it's hex value as follows:

int a[] = { 0, 1, 1, 0 };

I would like to take each value of the array to represent it as binary and convert it to a hex value. In this case:

0x6000000000000000; // 0110...0

it also has to be packed to the right with 0's to be 64 bits (i am on a 64 bit machine).

Or i could also take the array elements, convert to decimal and convert to hexadecimal it that's easier... What you be the best way of doing this in C++?

(this is not homework)

A: 

Here's a rough answer:

int ConvertBitArrayToInt64(int a[])
{
    int answer = 0;

    for(int i=0; i<64; ++i)
    {
        if (isValidIndex(i))
        {
            answer = answer << 1 | a[i];
        }
        else
        {
            answer = answer << 1;
        }
    }
    return answer;
}
abelenky
What is `isValidIndex()`?
ArunSaha
It is a function that we do not have enough information from the original question to implement. The implementation (or more likely, a suitable replacement) is left as an exercise to the implementor.
abelenky
+1  A: 

std::bitset<64>::to_ulong() might be your friend. The order will probably be backwards (it is unspecified, but typically index 3 will be fetched by right-shifting the word by 3 and masking with 1), but you can remedy that by subtracting the desired index from 63.

#include <bitset>

std::bitset<64> bits;

for ( int index = 0; index < sizeof a/sizeof *a, ++ index ) {
    bits[ 63 - index ] = a[ index ];
}

std::cout << std::hex << std::setw(64) << std::setfill('0')
          << bits.to_ulong() << std::endl;
Potatoswatter
I think he's trying to generate an `unsigned long` from an array of `int` . He doesn't have one to pass into `bitset` (I had already discarded this idea, but maybe I read the question wrong).
Mark B
@Mark: Yeah, I edited the answer to reverse the sense like that. `bitset` works both ways.
Potatoswatter
+1 but I was wondering, does `std::copy` work with `bitset` ?
Mark B
@Mark: Nope. Indexing only.
Potatoswatter
+3  A: 

The following assumes that your a[] will only ever use 0 and 1 to represent bits. You'll also need to specify the array length, sizeof(a)/sizeof(int) can be used in this case, but not for heap allocated arrays. Also, result will need to be a 64bit integer type.

for (int c=0; c<array_len; c++)
  result |= a[c] << (63-c);

If you want to see what it looks like in hex, you can use (s)printf( "%I64x", result )

jay.lee
need to subtract from 63… shift by 64 is implementation-defined.
Potatoswatter
@Potatoswatter good catch, edited.
jay.lee
Thanks, this works great. I had to make the result type unsigned long long and cast the a[c] to unsigned long long also. Thanks!
gprime
A: 

byte hexValues[16];

for(int i = 15; i >= 0; i--) { hexValues = a[i*4] * 8 + a[i*4-1] * 4 + [i*4-2] * 2 + a[i*4-3]; }

This will give you an array of bytes where each byte represents one of your hex values.

Note that each byte in hexValues will be a value from 0 to 16.

Hannesh
+1  A: 
unsigned long long answer= 0;
for (int i= 0; i<sizeof(a)/sizeof(a[0]); ++i)
{
    answer= (answer << 1) | a[i];
}

answer<<= (64 - sizeof(a)/sizeof(a[0]));

Assumptions: a[] is at most 64 entries, is defined at compile time, and only contains 1 or 0. Being defined at compile time sidesteps issues of shifting left by 64, as you cannot declare an empty array.

MSN
It can have more than 64 entries, but i like this
gprime
@gprime, if it has more than 64 entries, what is the expected behavior?
MSN
@MSN there will never be more that 64...i would have to use a different datastructure if i wanted to. But i coded into my program to not attempt to perform the calculations if it's more than 64.
gprime