combining bytes to make a double?

P

Phillip Rhodes

Hi all, I have a question I hope someone can help me with:

I'm doing some communication over a socket, and have need to send
and receive values of type double. I'm doing everything in terms
of single byte reads and writes to the socket, so what I need to do
is take the individual bytes I receive, that represent a double, and
actually turn them into a double. This I'm struggling to figure
out.

I can easily combine the bytes into a container of some sort
(like say a long) that has the same bit pattern as the double
I want. For example, I can get to the point of having a long
that looks like 0001 1110 1000 0000 for 7.5d. But I can't
seem to get that into a double. A simple cast doesn't appear
to work, and I'm not sure what else to try.

Any help or ideas is greatly appreciated.


Thanks,

Phillip Rhodes
 
L

Larry I Smith

Phillip said:
Hi all, I have a question I hope someone can help me with:

I'm doing some communication over a socket, and have need to send
and receive values of type double. I'm doing everything in terms
of single byte reads and writes to the socket, so what I need to do
is take the individual bytes I receive, that represent a double, and
actually turn them into a double. This I'm struggling to figure
out.

I can easily combine the bytes into a container of some sort
(like say a long) that has the same bit pattern as the double
I want. For example, I can get to the point of having a long
that looks like 0001 1110 1000 0000 for 7.5d. But I can't
seem to get that into a double. A simple cast doesn't appear
to work, and I'm not sure what else to try.

Any help or ideas is greatly appreciated.


Thanks,

Phillip Rhodes

IF the sender and receiver are the same Operating System
and architecture (e.g. 32 bit Intel on both ends), you could
use a union.
Here are some code snips:

// overlay a double and a char buffer into the same memory
// area.
union DblBuf
{
double d;
char buf[sizeof(double)];
};

// on the sending end...
DblBuf db;

db.d = 123.456;

// sender writes the bytes of the double to the socket
for (int i = 0; i < sizeof(double); i++)
// write db.buf to the socket


// on the receiving end...
DblBuf db;

// receiver reads the bytes of a double from the socket:
for (int i = 0; i < sizeof(double); i++)
// read from the socket into db.buf

// db.d now contains the double.

The above approach won't work if the machines have
different OS or arch (e.g. Intel to Sparc, Win32 to Linux64, etc).
In that case, you need to send ASCII text (e.g. "123.456" across
the socket) and convert it back to a double on the receiving
end.

Larry
 
S

Stuart MacMartin

Actually, you just have to know the format of the double in the
message. If the sender and receiver just differ in endianness, you
might still find it easiest to decide on say little endian for the
message, and convert the doubles at the sender or receiver as required.

Of course, if performance isn't an issue and you can choose your
message format and the sender and receiver might not have the same
format for doubles, text might be easiest to code and debug. Otherwise
you'll want to use a union as Larry described.

Stuart
 
P

Phillip Rhodes

Larry said:
> // overlay a double and a char buffer into the same memory
// area.
union DblBuf
{
double d;
char buf[sizeof(double)];
};

thanks Larry, the union approach works great. Sadly,
I have used unions so infrequently that I don't think
the idea of doing it that way would have
ever crossed my mind.
The above approach won't work if the machines have
different OS or arch (e.g. Intel to Sparc, Win32 to Linux64, etc).
In that case, you need to send ASCII text (e.g. "123.456" across
the socket) and convert it back to a double on the receiving

right, those issues are why I'm doing all this. I'm defining
the canonical data representation(s) for going over the wire and
the creating the code to normalize everything to that format (as needed)
on the respective platforms. Needless to say, this is gobs of fun. :)


Thanks again.


TTYL,

Phil
 
M

Maxim Yegorushkin

On Sun, 10 Jul 2005 00:47:05 +0400, Larry I Smith

[]
IF the sender and receiver are the same Operating System
and architecture (e.g. 32 bit Intel on both ends), you could
use a union.

I don't see why one needs a union for that case. You can read from or
write to a double directly.

double d;
write(fd, &d, sizeof(d));
read(fd, &d, sizeof(d));
 
L

Larry I Smith

Maxim said:
On Sun, 10 Jul 2005 00:47:05 +0400, Larry I Smith

[]
IF the sender and receiver are the same Operating System
and architecture (e.g. 32 bit Intel on both ends), you could
use a union.

I don't see why one needs a union for that case. You can read from or
write to a double directly.

double d;
write(fd, &d, sizeof(d));
read(fd, &d, sizeof(d));

Because the he said in the original post that
single-byte read/write was part of the requirement
(i.e. he can not read/write more than one byte at a time).

Larry
 
P

Polaris

I'm just curious, why do you have to read/write the socket 1 byte at a time?

Polaris
 
P

Phillip Rhodes

Polaris said:
I'm just curious, why do you have to read/write the socket 1 byte at a time?

It turns out that I don't really. I just got started thinking in terms
of doing it that way for some reason, and that assumption got lodged in
my head. Now that I've thought about it, I'm pretty sure that I can
actually do what I'm trying to do, without having to read each byte in a
separate recv() call.


After all, if I know how many bytes to read, using recv() in a for
loop, it's just the same to use that value in the recv() call itself.

Chalk it up as a "brain fart" I guess. :)


TTYL,

Phil
 
P

Polaris

That's sounds better.

recv() returns the actual number of bytes received. There is a message group
"alt.winsock.programming", guess that's better place to get more info on
socket programming.

Polaris
 
G

Greg

Phillip said:
Larry said:
// overlay a double and a char buffer into the same memory
// area.
union DblBuf
{
double d;
char buf[sizeof(double)];
};

thanks Larry, the union approach works great. Sadly,
I have used unions so infrequently that I don't think
the idea of doing it that way would have
ever crossed my mind.
The above approach won't work if the machines have
different OS or arch (e.g. Intel to Sparc, Win32 to Linux64, etc).
In that case, you need to send ASCII text (e.g. "123.456" across
the socket) and convert it back to a double on the receiving

right, those issues are why I'm doing all this. I'm defining
the canonical data representation(s) for going over the wire and
the creating the code to normalize everything to that format (as needed)
on the respective platforms. Needless to say, this is gobs of fun. :)

It's also reinventing the wheel. For sending data types and data
structures over a network, by the far the easiest and most
interoperable approach would be to use ASN.1 notation and a BER library
(Basic Encoding Rules) to encode and decode the data on both ends of
the connection. Not only do well-debugged, freely available
implementations exist on every major platform, but the BER notation
being self-describing is quite robust. It is the data encoding format
used by dozens of standards and innumerable RFCs.

The problem with the union approach is that it is very compiler- and
platform-specific which negates much of the usefullness of a network
and its ability to connect machines of different types. But sending
whatever the compiler produces adheres to explicit standard or external
reference and is inherently fragile even between machines of the same
type.

Greg
 
L

Larry I Smith

Greg said:
[snip]

It's also reinventing the wheel. For sending data types and data
structures over a network, by the far the easiest and most
interoperable approach would be to use ASN.1 notation and a BER library
(Basic Encoding Rules) to encode and decode the data on both ends of
the connection. Not only do well-debugged, freely available
implementations exist on every major platform, but the BER notation
being self-describing is quite robust. It is the data encoding format
used by dozens of standards and innumerable RFCs.
[snip]

Could you provide some links to Linux Open Source libs req'd to
do the job - libs to be linked to a C++ app.
Google hasn't helped much with this.

Thanks,
Larry
 
P

Phillip Rhodes

Greg wrote:

It's also reinventing the wheel. For sending data types and data
structures over a network, by the far the easiest and most
interoperable approach would be to use ASN.1 notation and a BER library
(Basic Encoding Rules) to encode and decode the data on both ends of
the connection. Not only do well-debugged, freely available
implementations exist on every major platform, but the BER notation
being self-describing is quite robust. It is the data encoding format
used by dozens of standards and innumerable RFCs.

Hmmm... I have to admit, I'm not very familiar with ASN.1. I'll look
into it, but I suspect it may be overkill for what I'm trying to do.
I'll definitely look it up and take a look though.


TTYL,

Phil
 
M

msalters

Greg schreef:
It's also reinventing the wheel. For sending data types and data
structures over a network, by the far the easiest and most
interoperable approach would be to use ASN.1 notation and a BER library
(Basic Encoding Rules)

Even easier than text? I mean, reading and writing "1.0" is very easy.
Best of all, if it doesn't work you can look at the raw bits and
understand them. Try that with ASN.1

There's a good reason most RFCs use text and not ASN.1

HTH,
Michiel Saltres
 
L

lionet1

Text is a very fine thing. However, you might lose precision while
converting back and forth the decimal-based text format.
 
P

Phillip Rhodes

http://lionet.info/asn1c is a free ASN.1 compiler.

Awesome, thanks for the link. I'm not 100% sure
I need ASN.1 for the problem I'm working on right now,
but it definitely looks like something I should get
familiar with. I'll definitely be downloading
and looking at this.


Thanks again,


Phillip
 

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
474,432
Messages
2,571,681
Members
48,796
Latest member
Greg L.

Latest Threads

Top