std::bitset, standard and endianess

S

SpOiLeR

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 "0011000011111000"

=> 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
 
V

Victor Bazarov

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

q2: Is std::bitset::to_string() part of standard?
Yes.

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 "0011000011111000"

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

If I understand my docs well, on machine with different endianess, same
code will result in different string.

Your understanding is wrong.
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?

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

V
 
A

Andrey Tarasevich

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

It is a part of the standard library.
q2: Is std::bitset::to_string() part of standard?
Yes.

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 "0011000011111000"

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

If I understand my docs well, on machine with different endianess, same
code will result in different string.

No. The resultant string will contain the binary representation of
number 12536 (decimal), possibly with extra leading zeros. In binary
representation 12536 is "0011000011111000". It doesn't depend on the
endianness of the hardware platform. There's nothing in the
What does standard say about it: will
string output always have most significant bits on lowest string positions,
Yes.

or it is like my docs say?

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

SpOiLeR

There's nothing in the
specification of 'std::bitset<>' that depends on the endianness of the
hardware platform in any way.

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 = b16;
for (i=8; i<16; i++) b8_higher[i-8] = b16;

unsigned char low, high;

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

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?
 
H

Howard Hinnant

SpOiLeR said:
There's nothing in the
specification of 'std::bitset<>' that depends on the endianness of the
hardware platform in any way.

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 = b16;
for (i=8; i<16; i++) b8_higher[i-8] = b16;

unsigned char low, high;

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

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?


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:
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 .

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):
Character position N - 1 corresponds to bit position zero. Subsequent
decreasing character positions correspond to increasing bit positions.

#include <bitset>
#include <iostream>

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

0010110001001000
0001001000110100

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 ? 1: 0);
std::cout << '\n';

0010110001001000

-Howard
 
S

SpOiLeR

SpOiLeR said:
There's nothing in the
specification of 'std::bitset<>' that depends on the endianness of the
hardware platform in any way.

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 = b16;
for (i=8; i<16; i++) b8_higher[i-8] = b16;

unsigned char low, high;

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

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?


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:
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 .

Excellent!

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):
Character position N - 1 corresponds to bit position zero. Subsequent
decreasing character positions correspond to increasing bit positions.

#include <bitset>
#include <iostream>

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

0010110001001000
0001001000110100

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 ? 1: 0);
std::cout << '\n';

0010110001001000

-Howard


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

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top