Bitfield structs and suggestion
Don Clugston
dac at nospam.com.au
Tue Mar 21 00:13:19 PST 2006
Miles wrote:
> Wolfgang Draxinger wrote:
>> Now with SDL I've encountered a problem: SDL makes use of serval
>> bitfields and I've no idea, how to interface them to D.
>
> I would like to make use of this thread and ask Walter why it was chosen
> to keep bitfields out of D. Since D has C ABI support, inline assembly,
> structs and unions, it seems natural to have bitfields also, to
> complement low-level programming capabilities and simplify interfacing
> with C code.
>
> Recently I needed to parse and construct float numbers, and I had to do
> all this funny shift stuff in order to translate ieee754.h to a D
> module. The final result was ugly and also more error-prone compared to
> C (yes, abusing bit shifts made D code look worse than C).
>
> Something I think that D could improve over C in this field is to take
> bitfields to the next step and make them endian-aware. If you look into
> ieee754.h, you will find something like:
>
> union ieee754_float {
> float f;
>
> struct {
> #if __BYTE_ORDER == __BIG_ENDIAN
> unsigned int negative:1;
> unsigned int exponent:8;
> unsigned int mantissa:23;
> #endif
> #if __BYTE_ORDER == __LITTLE_ENDIAN
> unsigned int mantissa:23;
> unsigned int exponent:8;
> unsigned int negative:1;
> #endif
> } ieee;
> };
>
> This is the raw definition of an IEEE 32-bit float number. Things gets
> worse for 64-bit and 80-bit floats. The byte-order dependency could be
> abstracted by a possible D implementation of bitfields by specifying an
> attribute that defines if bits should be in register order or in memory
> order. For example:
>
> union ieee754_float {
> float f;
>
> pragma(bitfield_order, register, 4)
> struct {
> uint negative:1; // most significant bits of a 32-bit register
> uint exponent:8;
> uint mantissa:23; // least significant bits of a 32-bit register
> } ieee;
> };
>
> Or, for example, when the position in memory is important (communicating
> with microcontrolled devices via a serial line):
>
> union my_float {
> byte raw[4];
>
> pragma(bitfield_order, memory)
> struct {
> uint negative:1; // first bits in memory
> uint exponent:8;
> uint mantissa:23; // last bits in memory
> };
> };
>
> Another suggestion, not related to bitfields but related to floats,
> would be to add these properties (.negative, .mantissa, .exponent and
> .quiet_nan) to the floating-point types of D.
I agree, that would be great, it would allow us to remove the ugly
cast(char [])cast(void *).. hacks from std.math.
(It would also allow them to be accessed at compile time, which I would
find very useful).
Maybe only the mantissa and exponent are required, the position of the
negative bit is fixed in the exponent, isn't it?
(provided that mantissa is an integral type).
Immediate interesting application: efficiently converting random
integers into a random real in the range 0..1, just by storing the int
into the mantissa of a real.
More information about the Digitalmars-d
mailing list