Boost logo

Boost :

Subject: Re: [boost] [endian] Project not maintained
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2016-04-04 13:04:42


On 2016-04-04 19:37, Peter Dimov wrote:
> Andrey Semashev wrote:
>
>> > void write_be32( uint_least32_t n, unsigned char p[4] )
>> > {
>> > // I assume CHAR_BIT of 8 here
>> >
>> > /* assert( n < 2^32 ); */
>> >
>> > p[0] = ( n >> 24 ) & 0xFF;
>> > p[1] = ( n >> 16 ) & 0xFF;
>> > p[2] = ( n >> 8 ) & 0xFF;
>> > p[3] = n & 0xFF;
>> > }
>>
>> For example, uint_least32_t could have non-base-2 representation, so
>> as unsigned char, so the bit patterns that are stored to p would be
>> also not base-2.
>
> The representation of uint_least32_t doesn't matter. The expression n &
> 0xFF gives you a number between 0 and 255 that contains the lowest 8
> VALUE bits of n, which is not the same as the STORAGE bits of n. In no
> possible representation would an uint_least32_t n with a value (m * 256
> + 232) give you something other than 232 from (n & 0xFF).

With (n & 0xFF) you get a bit pattern which on the current architecture
is interpreted as a number of 232. This bit pattern may be interpreted
differently on another architecture.

If you say that write_be32 is formally portable then it is imperative
that the bit pattern it produces is interpreted equivalently on all
architectures. To guarantee that, write_be32 might have do something
else than what is written above or what we call byte swapping. Or
otherwise you have to force the representation of input.

>> I agree that byte swapping is rarely the end goal. But in practice,
>> with some restrictions, like assuming base-2 integers and 8-bit bytes
>> across all systems you're planning to run your code on, endian
>> conversions can serve as a means of data serialization.
>
> And my point is that the interface you gave handles representational
> differences with the same ease as it handles differences that are
> limited to a byte swap.
>
> It's actually the same for float. If your base is
>
> void write_le32( float x, unsigned char p[4] );
>
> the interface remains the same no matter what the representation of x.
> What matters is that you get a little-endian 32 bit IEEE float in p.

On a platform with non-IEEE floats, does write_le32 have to convert to
IEEE format before producing the bits in p? What if the x value on the
current platform is not representable in IEEE float?

> If however you go for
>
> float byteswap( float x );
>
> then things get hairy even if restricted to IEEE, because an ordinary
> number may turn into a signaling NaN when byteswapped.

Absolutely agreed.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk