# Serialize - data packing

This topic is 4275 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

let's say i have 2 floats. i want to pack them into one big unit (not an array or vector).

##### Share on other sites
struct float2
{
float f1,f2;
};

Where is the problem??

##### Share on other sites
Perhaps you're looking for a double? Set the high 4 bytes to the first float and the next 4 low bytes to the second?

##### Share on other sites
dbzprogrammer how to do this?

##### Share on other sites
c/c++ :
union U{	struct {		float f1,f2;	};	double d;};...U u;u.f1 = your_float1;u.f2 = your_float2;your_double = u.d;

##### Share on other sites
I understood the concept, and after a quick pull, I double checked my mental code.

Fundamentals, bits are what makes a byte. The higher the bit in the sequence, the greater the number it represents. Each bit represents a 2^x number. Normally, we would copy byte for byte, using the & (bit-wise AND) with 255 to determine which bits we want. However, we're doing 4 bytes at a time, so we will have to use the number 4294967295. This sets 32 bits to '1's.

double PackFloats(float f1, float f2){  return ((double)f1 << 32) + ((double)f2);}

EDIT: Hit the button too soon. The << is an operator that "shifts" bits. Basically, you're telling the computer that you want to fill in 4 bytes of the double with f1, starting at bit 32, and ends up at bit 63, the last bit (remember, we have bit 0 that makes it a total of 64 bits).

##### Share on other sites
Um, packing two small units into a meaningful larger unit only works with unsigned integers. The last bit of code gives you a structure of either two floats or a double.

u.f1 = your_float1;
u.f2 = your_float2;
your_double = u.d;

Is basically filling your_double with meaningless bits.

The
struct float2{
float f1,f2;
}
is most likely what the OP is looking for.

##### Share on other sites
Quote:
 Original post by CocalusUm, packing two small units into a meaningful larger unit only works with unsigned integers. The last bit of code gives you a structure of either two floats or a double.u.f1 = your_float1;u.f2 = your_float2;your_double = u.d;Is basically filling your_double with meaningless bits.The struct float2{ float f1,f2;}is most likely what the OP is looking for.

He has a good point, as floating point precision would get messed up...

But he's just trying to back it up so he could extract it later, would that affect it?

##### Share on other sites
Let me add to my previous post here.

How would you de-searilize it?

With a function like the one before, except those numbers that I showed you would actually come into play. Observe:

struct MyStruct{  float f1;  float f2;}MyStruct ExtractDouble(double tempD){  MyStruct returnS;  returnS.f2 = tempD & 4294967295;  returnS.f1 = (tempD >> 32) & 4294967295;  return returnS;}

##### Share on other sites
Quote:
 Original post by dbzprogrammerdouble PackFloats(float f1, float f2){ return ((double)f1 << 32) + ((double)f2);}

This works with interegs but not with doubles:
error C2296: '<<' : illegal, left operand has type 'double'

##### Share on other sites
If he's just packing it to extract it latter then the 2 float structure is what he wants. Using a double is just confusing

This has nothing to do with precision the data structure of a float. They just don't pack like that (the double is as usefull as a random bunch of bits).

A float is
1 sign bit 8 Exponent bits 23 Precision Bits
A double is
1 sign bit 11 Exponent bits 53 Precision Bits

So 2 floats packed into a double like that is
1 sign 8 exponent 23 Precision 1 sign 8 exponent 23 Precision
Where only the first one sign bit lines up with the double.

You can pull the floats back out. But why use a double at all when the structure works just as well and is descriptive of what you're doing.

(Note I'm assuming the compiler packs structures on 4 byte alignments)

##### Share on other sites
Quote:
 Original post by CocalusIs basically filling your_double with meaningless bits.

But it works...
#include <iostream>using namespace std;union U{	struct {		float f1,f2;	};	double d;};int main(){	//Serialize	U u;	u.f1 = 2.8;	u.f2 = 3.1;	double d = u.d;	//Deerialize	U u2;	u2.d = d;	float f1 = u2.f1;	float f2 = u2.f2;	cout << f1 << endl << f2 << endl;}/*Output:2.83.1*/

OK...
I would use just a struct as I said in my first post.
Or the std::pair class.

##### Share on other sites
There are possibilities... Like sending out using a network lib that accepts doubles :P Some sort of constraint.

##### Share on other sites
My point is that involving the double is unneeded and confusing.

U u;
u.f1 = 2.8;
u.f2 = 3.1;

float f1 = u.f1;
float f2 = u.f2;

works just as well and is easier to understand.

##### Share on other sites
It is confusing and is it not needed he can use unsigned __int64 too(better than the double)... but he asked how to do it and I just answered.

##### Share on other sites
If you want to serialize it to something like a vector<char> buffer, you could write a bunch of serialization/unserialization functions:

(alternatively, and probably more cleanly, you could make these Get/Put functions member functions of some class, and manage the vector or some other buffer behind closed doors.)

void PutFloat( std::vector<char>& vec, float data ){   vec.insert( vec.end(), reinterpret_cast<char const*>( &data ), reinterpret_cast<char const*>( &data + 1 ) );}float GetFloat( std::vector<char> const& vec, std::size_t index ){   if( index < index + sizeof(float) && index + sizeof(float) <= vec.size() )   {      float val = *reinterpret_cast<float const*>( &vec[index] );      return val;   }   //access would overflow vector boundaries - throw something?   return 0.0f;}

[Edited by - RDragon1 on April 1, 2006 4:40:10 PM]

##### Share on other sites
Quote:
 Original post by KambizIt is confusing and is it not needed he can use unsigned __int64 too(better than the double)... but he asked how to do it and I just answered.

I was just trying to get across that there are very few good reasons for ever doing it like that.

##### Share on other sites
Quote:
 Original post by Eitsch...not an array or vector...

Quote:
 Original post by RDragon1If you want to serialize it to something like a vector buffer,...

##### Share on other sites
Quote:
 Original post by KambizQuote: Original post by Eitsch...not an array or vector...Quote: Original post by RDragon1If you want to serialize it to something like a vector buffer,...

Oops, good call. I saw someone mentioning network serialization, so I threw that up...

That just raises the question - why not a vector?

##### Share on other sites
Quote:
 Original post by RDragon1That just raises the question - why not a vector?

Unrelated to your question, but also a valid one: Why not endianness?

OP, you might want to check the enginuity articles for some developed ideas on serialization that might inspire you.

##### Share on other sites
Why not a vector?
That is a good question... I know another one : why do you want to serialize just 2 floats??
...and another one : Why do you need serialization?

##### Share on other sites
Quote:
Original post by owl
Quote:
 Original post by RDragon1That just raises the question - why not a vector?

Unrelated to your question, but also a valid one: Why not endianness?

OP, you might want to check the enginuity articles for some developed ideas on serialization that might inspire you.

*nod*

For endianness, I would pick the dominant platform (the one used the most, if there is one), and pack things in using the native endianness. That gives you the most efficient and clean code where you care about it most. Then, on the non-dominant supported platform, have the packing/unpacking convert to/from the dominant endianness.

##### Share on other sites
i need it to send a big structure over network (i am using simple sockets). the big structure has many dynamic stuff and pointers so i wanted to put it into one big "buffer" (a buffer where i don't loose precision if i have floats). RDragon1s code looks good. thanks.

##### Share on other sites
You might want to worry about endianness, although if the data is only going to be used by the average windows machine, it probably doesn't matter.

##### Share on other sites
have allready functions to swap bytes.

##### Share on other sites

This topic is 4275 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628719
• Total Posts
2984386

• 25
• 11
• 10
• 15
• 14