# Converting a string to binary

• 06-30-2003
laasunde
Converting a string to binary
I have a couple of question about the Converting a string to binary article on this site.

First of all, CHAR_BIT - Is this a const int = 8 ? Im assumiong it's been declared in one of the headers.

Secondly, this code snip is found in the print_bits method
Code:

```  for ( unsigned i = 0; i < n_bits; ++i ) {     std::cout<< !!( val & 1 );     val >>= 1;   }```
Whats the point of using two ! when doing the cout ?

whats does val >>=1 do ?

appreciate any response.
• 06-30-2003
Zach L.
>> CHAR_BIT - Is this a const int = 8 ? Im assumiong it's been declared in one of the headers.

Yes. <climits>/<limits.h> I believe.

>> whats does val >>=1 do ?

Bit shifting. Say you have the following byte:

1011 1011

Shifting to the right by one bit (>> and >>=) produces:

0101 1101

>> Whats the point of using two ! when doing the cout ?

I think it is there to ensure the value has no extra bits in it (i.e. for any non-zero n, !n = 0 and !!n = 1), but it seems to me to be redundant. You shouldn't get extra bits set when you AND with 1 because the rest of the bits (of 1) are all 0s.
• 06-30-2003
laasunde

Quote:

Originally posted by Zach L.

>> whats does val >>=1 do ?

Bit shifting. Say you have the following byte:

1011 1011

Shifting to the right by one bit (>> and >>=) produces:

0101 1101
so >> and >>= means the same thing ?
• 06-30-2003
Zach L.
The difference is like that between + and +=.

val >>= 1 <-> val = val >> 1
• 06-30-2003
laasunde
Of course...
• 07-01-2003
laasunde
I've been playing around with the above example and couldnt this be an even simpler solution ?

Code:

``` #include <iostream> #include <climits> #include <string> template <typename T> void print( T val ) {   for( int bit=128; bit > 0; bit /= 2) {       int sum = (val & bit);       if (sum > 0)           cout << "1";       else           cout << "0";   } } int main() {   std::string s = "This is a test";   std::string::iterator it;   for ( it = s.begin(); it != s.end(); it++ ) {         print ( *it );         std::cout<<"  "<< *it <<std::endl;     }   system("PAUSE");   return 0; }```
• 07-01-2003
Zach L.
Perhaps a bit more direct since it is starting from the left (most-significant) bit, so you need not reverse it first.

I'd watch out for the hardcoded initial value of bit though, as it will only work for 1 byte values (the CHAR_BIT * sizeof(val) is the way to get around this).

This is where you could use the double negation trick:

cout << !!(bit & val);

as you actually would be using it to convert non-zero numbers into the value 1.

And with that, yeah, it definitely does seem a bit simpler, or at least shorter.
• 07-01-2003
Casey
>>First of all, CHAR_BIT - Is this a const int = 8 ?
It's an implementation defined value, usually defined in <climits> like so (for octets)

#define CHAR_BIT 8

>>Whats the point of using two ! when doing the cout ?
It normalizes a value into either 0 or 1. If you only use one ! then the bits will be swapped, 0101 will be 1010 and that would be wrong. So the first ! changes the values to 0 and 1, and the second swaps them so that they hold the right 0 and 1 values.

>>whats does val >>=1 do ?
It shifts the bits in val right by one and assigns the result to val.
• 07-01-2003
laasunde
Quote:

Originally posted by Casey

>>Whats the point of using two ! when doing the cout ?
It normalizes a value into either 0 or 1. If you only use one ! then the bits will be swapped, 0101 will be 1010 and that would be wrong. So the first ! changes the values to 0 and 1, and the second swaps them so that they hold the right 0 and 1 values.

Thanks for your feedback. Im not 100% sure i follow you on the above. Could you please give me an example where !! work but not using a ! doesnt work ?

Zach L. : A bit lazy on my part not to include CHAR_BIT + sizeof( val )
• 07-01-2003
Casey
This should explain it
Code:

```#include <iostream> #include <climits> #include <string> template <typename T> void print_bits1 ( T val ) {   unsigned int n_bits = sizeof ( val ) * CHAR_BIT;   for ( unsigned i = 0; i < n_bits; ++i ) {     std::cout<< !( val & 1 );     val >>= 1;   } } template <typename T> void print_bits2 ( T val ) {   unsigned int n_bits = sizeof ( val ) * CHAR_BIT;   for ( unsigned i = 0; i < n_bits; ++i ) {     std::cout<< !!( val & 1 );     val >>= 1;   } } int main() {     print_bits1(1U);     std::cout<<std::endl;     print_bits2(1U); }```
• 07-01-2003
Zach L.
Essentially, you want anything that yields a non-zero value to become 1, and 0 to stay 0.

Since any non-zero number is true (say x != 0), then !x is false (0), and !(!x)=!!x =1 (since ! will return 1 for true, not just an arbitrary number).

Similarly, !0=1 and !1=0, so !!0=0.

>> A bit lazy on my part not to include CHAR_BIT + sizeof( val )..

Understandable, I just thought I'd point it out. :)

Actually, I was off as well, it should be (1 << (sizeof(val) * CHAR_BIT - 1)).
• 07-01-2003
laasunde
Quote:

Originally posted by Zach L.

Since any non-zero number is true (say x != 0), then !x is false (0), and !(!x)=!!x =1 (since ! will return 1 for true, not just an arbitrary number).

Thanks a bunch, now I get it :)