Thread: Converting a string to binary

  1. #1
    Registered User
    Join Date
    Oct 2002
    Posts
    291

    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.

  2. #2
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    >> 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.
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  3. #3
    Registered User
    Join Date
    Oct 2002
    Posts
    291
    Thanks for your response.

    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 ?

  4. #4
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    The difference is like that between + and +=.

    val >>= 1 <-> val = val >> 1
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  5. #5
    Registered User
    Join Date
    Oct 2002
    Posts
    291
    Of course...

  6. #6
    Registered User
    Join Date
    Oct 2002
    Posts
    291
    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;
    }

  7. #7
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    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.
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  8. #8
    Registered User Casey's Avatar
    Join Date
    Jun 2003
    Posts
    47
    >>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.

  9. #9
    Registered User
    Join Date
    Oct 2002
    Posts
    291
    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 )

  10. #10
    Registered User Casey's Avatar
    Join Date
    Jun 2003
    Posts
    47
    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);
    }

  11. #11
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    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)).
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  12. #12
    Registered User
    Join Date
    Oct 2002
    Posts
    291
    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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Inheritance Hierarchy for a Package class
    By twickre in forum C++ Programming
    Replies: 7
    Last Post: 12-08-2007, 04:13 PM
  2. RicBot
    By John_ in forum C++ Programming
    Replies: 8
    Last Post: 06-13-2006, 06:52 PM
  3. can anyone see anything wrong with this code
    By occ0708 in forum C++ Programming
    Replies: 6
    Last Post: 12-07-2004, 12:47 PM
  4. Something is wrong with this menu...
    By DarkViper in forum Windows Programming
    Replies: 2
    Last Post: 12-14-2002, 11:06 PM
  5. ........ed off at functions
    By Klinerr1 in forum C++ Programming
    Replies: 8
    Last Post: 07-29-2002, 09:37 PM