std::bitset, standard and endianess

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • SpOiLeR

    std::bitset, standard and endianess

    Hi.

    q1: Is std::bitset<N> part of standard or it's compiler extension?

    q2: Is std::bitset::to _string() part of standard?

    q3: My documentation say this about std::bitset::to _string():

    "...each character is 1 if the corresponding bit is set, and 0 if it is
    not. In general, character position i corresponds to bit position N - 1 -
    i..."

    On my machine, it results in most significant bits being on lower positions
    in resulting string:

    unsigned int i = 12536;
    std::bitset<16> bs = i;
    std::string str = bs.to_string();

    which gives for str "00110000111110 00"

    => 0011 0000 1111 1000 == x30F8 == 12536

    If I understand my docs well, on machine with different endianess, same
    code will result in different string. What does standard say about it: will
    string output always have most significant bits on lowest string positions,
    or it is like my docs say?

    TIA
  • Victor Bazarov

    #2
    Re: std::bitset, standard and endianess

    SpOiLeR wrote:[color=blue]
    > q1: Is std::bitset<N> part of standard or it's compiler extension?[/color]

    Standard.
    [color=blue]
    > q2: Is std::bitset::to _string() part of standard?[/color]

    Yes.
    [color=blue]
    > q3: My documentation say this about std::bitset::to _string():
    >
    > "...each character is 1 if the corresponding bit is set, and 0 if it is
    > not. In general, character position i corresponds to bit position N - 1 -
    > i..."
    >
    > On my machine, it results in most significant bits being on lower positions
    > in resulting string:
    >
    > unsigned int i = 12536;
    > std::bitset<16> bs = i;
    > std::string str = bs.to_string();
    >
    > which gives for str "00110000111110 00"
    >
    > => 0011 0000 1111 1000 == x30F8 == 12536
    >
    > If I understand my docs well, on machine with different endianess, same
    > code will result in different string.[/color]

    Your understanding is wrong.
    [color=blue]
    > What does standard say about it: will
    > string output always have most significant bits on lowest string positions,
    > or it is like my docs say?[/color]

    The Standard does not concern itself with endianness. So, yes, the most
    significant bit will the at the beginning of the resulting string.

    V

    Comment

    • Andrey Tarasevich

      #3
      Re: std::bitset, standard and endianess

      SpOiLeR wrote:[color=blue]
      > ...
      > q1: Is std::bitset<N> part of standard or it's compiler extension?[/color]

      It is a part of the standard library.
      [color=blue]
      > q2: Is std::bitset::to _string() part of standard?[/color]

      Yes.
      [color=blue]
      > q3: My documentation say this about std::bitset::to _string():
      >
      > "...each character is 1 if the corresponding bit is set, and 0 if it is
      > not. In general, character position i corresponds to bit position N - 1 -
      > i..."
      >
      > On my machine, it results in most significant bits being on lower positions
      > in resulting string:
      >
      > unsigned int i = 12536;
      > std::bitset<16> bs = i;
      > std::string str = bs.to_string();
      >
      > which gives for str "00110000111110 00"
      >
      > => 0011 0000 1111 1000 == x30F8 == 12536
      >
      > If I understand my docs well, on machine with different endianess, same
      > code will result in different string.[/color]

      No. The resultant string will contain the binary representation of
      number 12536 (decimal), possibly with extra leading zeros. In binary
      representation 12536 is "00110000111110 00". It doesn't depend on the
      endianness of the hardware platform. There's nothing in the
      specification of 'std::bitset<>' that depends on the endianness of the
      hardware platform in any way.
      [color=blue]
      > What does standard say about it: will
      > string output always have most significant bits on lowest string positions,[/color]

      Yes.
      [color=blue]
      > or it is like my docs say?[/color]

      That's actually exactly what your docs say. You just have to interpret
      them at higher (logical) level.

      --
      Best regards,
      Andrey Tarasevich

      Comment

      • SpOiLeR

        #4
        Re: std::bitset, standard and endianess

        On Mon, 14 Mar 2005 16:09:05 -0800, Andrey Tarasevich wrote:
        [color=blue]
        > There's nothing in the
        > specification of 'std::bitset<>' that depends on the endianness of the
        > hardware platform in any way.[/color]

        So, if I write something like this:

        std::bitset<16> b16 (12345); // 12345 can fit in 16 bits
        std::bitset<8> b8_higher, b8_lower;

        unsigned int i;
        for (i=0; i<8; i++) b8_lower[i] = b16[i];
        for (i=8; i<16; i++) b8_higher[i-8] = b16[i];

        unsigned char low, high;

        // Casts OK because standard guarantees that char contains at least 8 bits
        low = static_cast <unsigned char> (b8_lower.to_ul ong ());
        high = static_cast <unsigned char> (b8_higher.to_u long ());

        Is it guaranteed that low will contain less significant bits of number
        contained in b16, and higher will contain more significant bits of that
        number?

        Comment

        • Howard Hinnant

          #5
          Re: std::bitset, standard and endianess

          In article <1eatpyqr3of7k$ .k2i9qf012d5l$. dlg@40tude.net> ,
          SpOiLeR <request@no_spa m.org> wrote:
          [color=blue]
          > On Mon, 14 Mar 2005 16:09:05 -0800, Andrey Tarasevich wrote:
          >[color=green]
          > > There's nothing in the
          > > specification of 'std::bitset<>' that depends on the endianness of the
          > > hardware platform in any way.[/color]
          >
          > So, if I write something like this:
          >
          > std::bitset<16> b16 (12345); // 12345 can fit in 16 bits
          > std::bitset<8> b8_higher, b8_lower;
          >
          > unsigned int i;
          > for (i=0; i<8; i++) b8_lower[i] = b16[i];
          > for (i=8; i<16; i++) b8_higher[i-8] = b16[i];
          >
          > unsigned char low, high;
          >
          > // Casts OK because standard guarantees that char contains at least 8 bits
          > low = static_cast <unsigned char> (b8_lower.to_ul ong ());
          > high = static_cast <unsigned char> (b8_higher.to_u long ());
          >
          > Is it guaranteed that low will contain less significant bits of number
          > contained in b16, and higher will contain more significant bits of that
          > number?[/color]

          Yes. The standard mandates that the bits will appear to be stored in
          little endian order as observed by the indexing operator:

          23.3.5p3:
          [color=blue]
          > When converting between an object of class bitset<N> and a value of some
          > integral type, bit position pos corresponds to the bit value 1 << pos .[/color]

          However, just in case we caught you napping, to_string is guaranteed to
          present the bits in big endian order: ;-)

          23.3.5.2p19 (describing to_string):
          [color=blue]
          > Character position N - 1 corresponds to bit position zero. Subsequent
          > decreasing character positions correspond to increasing bit positions.[/color]

          #include <bitset>
          #include <iostream>

          int main()
          {
          std::bitset<16> bs(0x1234);
          for (unsigned i = 0; i < 16; ++i)
          std::cout << (bs[i] ? 1: 0);
          std::cout << '\n';
          std::string srep = bs.to_string();
          std::cout << srep << '\n';
          }

          001011000100100 0
          000100100011010 0

          Fortunately bitsets constructed from strings are consistent with
          to_string and interpret the string in big endian order.

          std::bitset<16> bs2(srep);
          for (unsigned i = 0; i < 16; ++i)
          std::cout << (bs2[i] ? 1: 0);
          std::cout << '\n';

          001011000100100 0

          -Howard

          Comment

          • SpOiLeR

            #6
            Re: std::bitset, standard and endianess

            On Wed, 16 Mar 2005 02:04:46 GMT, Howard Hinnant wrote:
            [color=blue]
            > In article <1eatpyqr3of7k$ .k2i9qf012d5l$. dlg@40tude.net> ,
            > SpOiLeR <request@no_spa m.org> wrote:
            >[color=green]
            >> On Mon, 14 Mar 2005 16:09:05 -0800, Andrey Tarasevich wrote:
            >>[color=darkred]
            >>> There's nothing in the
            >>> specification of 'std::bitset<>' that depends on the endianness of the
            >>> hardware platform in any way.[/color]
            >>
            >> So, if I write something like this:
            >>
            >> std::bitset<16> b16 (12345); // 12345 can fit in 16 bits
            >> std::bitset<8> b8_higher, b8_lower;
            >>
            >> unsigned int i;
            >> for (i=0; i<8; i++) b8_lower[i] = b16[i];
            >> for (i=8; i<16; i++) b8_higher[i-8] = b16[i];
            >>
            >> unsigned char low, high;
            >>
            >> // Casts OK because standard guarantees that char contains at least 8 bits
            >> low = static_cast <unsigned char> (b8_lower.to_ul ong ());
            >> high = static_cast <unsigned char> (b8_higher.to_u long ());
            >>
            >> Is it guaranteed that low will contain less significant bits of number
            >> contained in b16, and higher will contain more significant bits of that
            >> number?[/color]
            >
            > Yes. The standard mandates that the bits will appear to be stored in
            > little endian order as observed by the indexing operator:
            >
            > 23.3.5p3:
            >[/color]
            [color=blue][color=green]
            >> When converting between an object of class bitset<N> and a value of some
            >> integral type, bit position pos corresponds to the bit value 1 << pos .[/color]
            >[/color]

            Excellent!
            [color=blue]
            > However, just in case we caught you napping, to_string is guaranteed to
            > present the bits in big endian order: ;-)
            >
            > 23.3.5.2p19 (describing to_string):
            >[color=green]
            >> Character position N - 1 corresponds to bit position zero. Subsequent
            >> decreasing character positions correspond to increasing bit positions.[/color]
            >
            > #include <bitset>
            > #include <iostream>
            >
            > int main()
            > {
            > std::bitset<16> bs(0x1234);
            > for (unsigned i = 0; i < 16; ++i)
            > std::cout << (bs[i] ? 1: 0);
            > std::cout << '\n';
            > std::string srep = bs.to_string();
            > std::cout << srep << '\n';
            > }
            >
            > 001011000100100 0
            > 000100100011010 0
            >
            > Fortunately bitsets constructed from strings are consistent with
            > to_string and interpret the string in big endian order.
            >
            > std::bitset<16> bs2(srep);
            > for (unsigned i = 0; i < 16; ++i)
            > std::cout << (bs2[i] ? 1: 0);
            > std::cout << '\n';
            >
            > 001011000100100 0
            >
            > -Howard[/color]

            Well, considering all this, std::bitset is one really nice object :)!!!
            Thanks everybody for your help...

            Comment

            Working...