floating point bitwise & and >> operations

J

jawilson2

Hello,
I have some data that stores two 16-bit integers in a 32-bit float, and
I would like to extract the data. I want to do something like

//-----------------------------------------------------------------
float *data;
short *buff;
int dataLen; //number of points in data

//other code...

for (i = 0; i < dataLen; i++)
{
buff[2*i] = (data & 0x0F); // place the lower 16 bits in the
first sample
buff[2*i + 1] = (data & 0xF0) >> 16; //place the upper 16 bits
(and bit shifted)in the second sample
}
//------------------------------------------------------------------

Does this make sense? I'm thinking it will involve casting the data
variable as an int/short somehow, using something like:

buff[2*i] = ( *(int*)&data ...); //found this on another forum, does
this work?

Any ideas?
Thanks!
 
V

Victor Bazarov

I have some data that stores two 16-bit integers in a 32-bit float,

WHY??? Can't you store those integers in a 32-bit _integer_? Use
'long' or 'unsigned long'.
and I would like to extract the data. I want to do something like

//-----------------------------------------------------------------
float *data;
short *buff;
int dataLen; //number of points in data

//other code...

for (i = 0; i < dataLen; i++)
{
buff[2*i] = (data & 0x0F); // place the lower 16 bits in the
first sample


That's not 16 bits. That's 4 bits. 0x0F == 0b00001111.
buff[2*i + 1] = (data & 0xF0) >> 16; //place the upper 16 bits
(and bit shifted)in the second sample


That's not "upper 16 bits". That's 0.
}
//------------------------------------------------------------------

Does this make sense?
No.

I'm thinking it will involve casting the data
variable as an int/short somehow, using something like:

buff[2*i] = ( *(int*)&data ...); //found this on another forum,
does this work?

Any ideas?


Don't do it.

V
 
J

jawilson2

WHY??? Can't you store those integers in a 32-bit _integer_? Use
'long' or 'unsigned long'.

Ok, let me clarify. I am reading data from hardware that compresses two
16-bit integer values into a single 32-bit float. I do not have any
control over this; the data is read into my program as a float.
That's not 16 bits. That's 4 bits. 0x0F == 0b00001111.

Oops. It is correct in my program (i.e. 0x0000FFFF).

So, given that the data must be stored in a float, and that the float
contains 2 16-bit integers, how do I get to the integers?
 
V

Victor Bazarov

Ok, let me clarify. I am reading data from hardware that compresses
two 16-bit integer values into a single 32-bit float. I do not have
any control over this; the data is read into my program as a float.

OK... Really? Wow. Floats, eh? Well, fine.
Oops. It is correct in my program (i.e. 0x0000FFFF).

So, given that the data must be stored in a float, and that the float
contains 2 16-bit integers, how do I get to the integers?

Non-portable way would be to extract chars (unsigned are probably better)
from the same address as your floats and reconstruct the integers:

void float_to_2_ints(float f, int i[2])
{
char* pc = static_cast<char*>(&f);
i[0] = (((unsigned char)pc[0]) << 8) | ((unsigned char)pc[1]);
i[1] = (((unsigned char)pc[2]) << 8) | ((unsigned char)pc[3]);
}

If the order of integers and/or chars in the float is different than the
one assumed here, you'd need to swap "pc[0/2]" with "pc[1/3]" and/or "i[0]"
with "i[1]". It all depends on the endianness of the hardware and your
system.

V
 
D

dan2online

Ok, let me clarify. I am reading data from hardware that compresses two
16-bit integer values into a single 32-bit float. I do not have any
control over this; the data is read into my program as a float.


Oops. It is correct in my program (i.e. 0x0000FFFF).

So, given that the data must be stored in a float, and that the float
contains 2 16-bit integers, how do I get to the integers?

At first, the question seems to be a topic of C programming not C++.

bitwise and shift perhaps depend on the compression format. I think you
need to clarify:
(1) two 16bit intergers only occupy the space of 32-bit float , or
(2) two 16bit integers stored in the float format (some hardwares
support, see your hardware manual)

In the first case, bitwise and >> are not correct in your code.
e.g. buff[2*i] = (data & 0x0000FFFF)
you cannot bitwise between float and short.
one simple way is to move or copy the memory content between them
directly.

for (i = 0; i < dataLen; i++)
{
/* data 32bit -> buff[2*i], buff[2*i+1] */
memmov( (char *) &(buff[2*i]), (char *) &data, sizeof(short) * 2)
.....
}

If your case is the second one, read your hardware manual by yourself.
 
A

Alex Buell

OK... Really? Wow. Floats, eh? Well, fine.

I *really* would like to know what sort of braindamaged hardware
does this and who the hardware designers were so I can shoot them.
 
V

Victor Bazarov

Alex said:
I *really* would like to know what sort of braindamaged hardware
does this and who the hardware designers were so I can shoot them.

I bet it's not hardware designers. Hardware just sends integers, two in
a row, probably. It's software designers who develop the interface to
expose them as 'float' types. Which actually kindof makes me think, what
if you instead of declaring the 'float*' on the receiving side, declare
'long*'? It's so much easier to unpack. And the sizes are most likely
the same... If you don't care about portability, cheat _them_ and right
there, where it all begins, instead of cheating yourself later.

V
 

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,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top