Bit twiddling/manipulation question

  • Thread starter Bartholomew Simpson
  • Start date
B

Bartholomew Simpson

I need to store two float values (each of which requires less 16 bit
storage), in a double data type.

Can anyone give me some macros to retrive/store values in the double ?

something along the lines of

STORE_LOWWORD(storage, value)
GET_LOWWORD(storage) /* returns value */


STORE_HIGHWORD(storage, value)
GET_HIGHWORD(storage) /* returns value */
 
S

SM Ryan

# I need to store two float values (each of which requires less 16 bit
# storage), in a double data type.
#
# Can anyone give me some macros to retrive/store values in the double ?

The format of float values is specific to the system, such DEC F or
IEEE single precision. You're not going to get a small bit of code that
runs everywhere. You can get a small bit of code that runs somewhere,
or a big chunk of code that runs everywhere.

You may end up doing some like
union {
struct {
unsigned signbit: 1;
int exponent: 6;
unsigned fraction: 9;
} parts;
short packed;
} smallreal;
union {
struct {
unsigned signbit: 1;
int exponent: 11;
unsigned fraction: 20;
} parts;
float packed;
} real;
real.packed = floatvalue;
smallreal.parts.signbit = real.parts.signbit;
smallreal.parts.exponent = real.parts.exponent-11;
smallreal.parts.fraction = real.parts.fraction>>11;

I used unions and structs because you cannot use a cast to convert
a float value to the same bit pattern now called an integer nor
vice versa. You have to pass through struct or char array using
union aliassing or memcpy.

In the DSP world there are small real formats, µlaw or something
like that. You can look that up and see if all these small
formats are acceptable and if transformers are already defined on
the systems that you want to run on.
 
M

Malcolm McLean

Bartholomew Simpson said:
I need to store two float values (each of which requires less 16 bit
storage), in a double data type.

Can anyone give me some macros to retrive/store values in the double ?

something along the lines of

STORE_LOWWORD(storage, value)
GET_LOWWORD(storage) /* returns value */


STORE_HIGHWORD(storage, value)
GET_HIGHWORD(storage) /* returns value */

#define STORE_LOWORD(storage, value) (((float *)&storage)[1] = value)
#define GET_LOWORD(storage) ((float *)&storage)[1]

hiword is left as an exercise. Swap the names if you are a little endian.
 
B

Barry Schwarz

Bartholomew Simpson said:
I need to store two float values (each of which requires less 16 bit
storage), in a double data type.

Can anyone give me some macros to retrive/store values in the double ?

something along the lines of

STORE_LOWWORD(storage, value)
GET_LOWWORD(storage) /* returns value */


STORE_HIGHWORD(storage, value)
GET_HIGHWORD(storage) /* returns value */

#define STORE_LOWORD(storage, value) (((float *)&storage)[1] = value)
#define GET_LOWORD(storage) ((float *)&storage)[1]

hiword is left as an exercise. Swap the names if you are a little endian.

Is there any guarantee that a double will be properly aligned for a
float?


Remove del for email
 
B

Barry Schwarz

I need to store two float values (each of which requires less 16 bit
storage), in a double data type.

Can anyone give me some macros to retrive/store values in the double ?

something along the lines of

STORE_LOWWORD(storage, value)
GET_LOWWORD(storage) /* returns value */


STORE_HIGHWORD(storage, value)
GET_HIGHWORD(storage) /* returns value */

You actually have a system which stores a float in 16 bits? The
standard requires at least six significant digits. That means it must
store all integer values between -999,999 and +999,999 exactly. Since
there are only 65,536 possible values in a 16-bit object, could you
tell us how this works.


Remove del for email
 
F

Flash Gordon

Barry Schwarz wrote, On 25/06/07 00:50:
Bartholomew Simpson said:
I need to store two float values (each of which requires less 16 bit
storage), in a double data type.

Can anyone give me some macros to retrive/store values in the double ?

something along the lines of

STORE_LOWWORD(storage, value)
GET_LOWWORD(storage) /* returns value */


STORE_HIGHWORD(storage, value)
GET_HIGHWORD(storage) /* returns value */
#define STORE_LOWORD(storage, value) (((float *)&storage)[1] = value)
#define GET_LOWORD(storage) ((float *)&storage)[1]

hiword is left as an exercise. Swap the names if you are a little endian.

Is there any guarantee that a double will be properly aligned for a
float?

No. There is also no guarantee that sizeof(double) >= 2*sizeof(float)
 
B

Barry Schwarz

Barry Schwarz wrote, On 25/06/07 00:50:
I need to store two float values (each of which requires less 16 bit
storage), in a double data type.

Can anyone give me some macros to retrive/store values in the double ?

something along the lines of

STORE_LOWWORD(storage, value)
GET_LOWWORD(storage) /* returns value */


STORE_HIGHWORD(storage, value)
GET_HIGHWORD(storage) /* returns value */
#define STORE_LOWORD(storage, value) (((float *)&storage)[1] = value)
#define GET_LOWORD(storage) ((float *)&storage)[1]

hiword is left as an exercise. Swap the names if you are a little endian.

Is there any guarantee that a double will be properly aligned for a
float?

No. There is also no guarantee that sizeof(double) >= 2*sizeof(float)

My question was about alignment, not size. To rephrase as a concrete
example, is it legal for a system to align doubles on 4-byte
boundaries but require a float to be on an 8-byte boundary.


Remove del for email
 
K

Keith Thompson

Barry Schwarz said:
Barry Schwarz wrote, On 25/06/07 00:50: [...]
Is there any guarantee that a double will be properly aligned for a
float?

No. There is also no guarantee that sizeof(double) >= 2*sizeof(float)

My question was about alignment, not size. To rephrase as a concrete
example, is it legal for a system to align doubles on 4-byte
boundaries but require a float to be on an 8-byte boundary.

Flash already answered your question (see "No", above); he also added
some information about size.

Yes, alignment requirements such as you describe are legal, and even
plausible. For example, suppose type float is 8 bytes, and the
hardware requires 8-byte alignment, but double is, say, 12 bytes, but
is implemented in software, so it only requires 4-byte alignment.
 
B

Barry Schwarz

Barry Schwarz said:
Barry Schwarz wrote, On 25/06/07 00:50: [...]
Is there any guarantee that a double will be properly aligned for a
float?

No. There is also no guarantee that sizeof(double) >= 2*sizeof(float)

My question was about alignment, not size. To rephrase as a concrete
example, is it legal for a system to align doubles on 4-byte
boundaries but require a float to be on an 8-byte boundary.

Flash already answered your question (see "No", above); he also added
some information about size.
Yes he did; I glossed over the "also".

This entire subthread was meant as a rhetorical question criticizing
Malcolm McLean's solution which cast a double* to a float*. I guess
I'm unknowingly approaching the RH level of subtlety.

Sorry Richard but you have company whether you want it or not.


Remove del for email
 
W

Walter Roberson

SM Ryan said:
You may end up doing some like
union {
struct {
unsigned signbit: 1;
int exponent: 6;
unsigned fraction: 9;
} parts;
short packed;
} smallreal;
union {
struct {
unsigned signbit: 1;
int exponent: 11;
unsigned fraction: 20;
} parts;
float packed;
} real;
real.packed = floatvalue;
smallreal.parts.signbit = real.parts.signbit;

If you store into a union via one type, you can't portably
retrieve from it using a different type, except in the case where
the two types field types are the same and share a common "prefix".

There is also no certainty of support for a bitfield of 20 bits.
"unsigned fraction" is "unsigned int fraction", and C only requires
int to be 16 bits wide (but larger is allowed for implementations.)
C89 at least does not support bitfields of type 'long' or
'unsigned long', the minimum required to be certain of 20 bit fields.
 
F

Flash Gordon

Barry Schwarz wrote, On 25/06/07 18:11:
Barry Schwarz said:
50: [...]
Is there any guarantee that a double will be properly aligned for a
float?
No. There is also no guarantee that sizeof(double) >= 2*sizeof(float)
My question was about alignment, not size. To rephrase as a concrete
example, is it legal for a system to align doubles on 4-byte
boundaries but require a float to be on an 8-byte boundary.
Flash already answered your question (see "No", above); he also added
some information about size.
Yes he did; I glossed over the "also".

This entire subthread was meant as a rhetorical question criticizing
Malcolm McLean's solution which cast a double* to a float*. I guess
I'm unknowingly approaching the RH level of subtlety.

Actually, I realised that, I was just supporting the possibility of
there being problems by suggesting yet another problem with his solution.

Of course, this stems from the OP trying to do something that may not be
possible.
Sorry Richard but you have company whether you want it or not.

Perhaps I am getting too subtle as well :)
 
K

Keith Thompson

There is also no certainty of support for a bitfield of 20 bits.
"unsigned fraction" is "unsigned int fraction", and C only requires
int to be 16 bits wide (but larger is allowed for implementations.)
C89 at least does not support bitfields of type 'long' or
'unsigned long', the minimum required to be certain of 20 bit fields.

That hasn't changed in C99; the only types guaranteed to be supported
for bit fields are int, unsigned int, signed int, and _Bool.
 

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

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top