Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

sockets: ntohl question

81 views
Skip to first unread message

Tom Impelluso

unread,
Jul 23, 2008, 11:51:35 PM7/23/08
to
Hello,

I am aware of the need for ntohl and htonl.
But floats?

I am aware of Beej's (Brian "Beej Jorgensen" Hall) implementation:
http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#htonsman

Yet, I devised my own kludge:
------------------------
uint32_t data, data1;
float num1;

i =read(descriptor, (char *) &data, sizeof(uint32_t));
data1 = ntohl(data);
num1 = *(float*) ( &data1);
--------------------------

This works for me; always has!
Now, mind you, I have done scientific coding.
And in an enviroment with extremley well-behaved floats,
where round-off has never been an issue.
And very little exceptions....

So...

Why does my simpler implementation work?
What problems could it cause?
Friends have advised me to use Jorgensen, but I do not see the need.
(I also have not gotten it to work)

Thanks,
tom
--
comp.lang.c.moderated - moderation address: cl...@plethora.net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.

Thomas Richter

unread,
Jul 25, 2008, 1:15:17 PM7/25/08
to
Tom Impelluso schrieb:

> Hello,
>
> I am aware of the need for ntohl and htonl.
> But floats?
>
> I am aware of Beej's (Brian "Beej Jorgensen" Hall) implementation:
> http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#htonsman
>
> Yet, I devised my own kludge:
> ------------------------
> uint32_t data, data1;
> float num1;
>
> i =read(descriptor, (char *) &data, sizeof(uint32_t));
> data1 = ntohl(data);
> num1 = *(float*) ( &data1);
> --------------------------

>

> Why does my simpler implementation work?

Depending on your definition of "works". It "works" if both sides use
the same representation for floating point, which is not guaranteed.
IEEE is pretty common these days, and used on a lot of, but not all
platforms.

> What problems could it cause?

Could return complete nonsense if the float representation on one end is
different from the other. IOW, your solution isn't portable.

So long,
Thomas

Kenneth Brody

unread,
Jul 27, 2008, 1:21:50 PM7/27/08
to
Tom Impelluso wrote:
>
> Hello,
>
> I am aware of the need for ntohl and htonl.
> But floats?
>
> I am aware of Beej's (Brian "Beej Jorgensen" Hall) implementation:
> http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#htonsman
>
> Yet, I devised my own kludge:
> ------------------------
> uint32_t data, data1;
> float num1;
>
> i =read(descriptor, (char *) &data, sizeof(uint32_t));
> data1 = ntohl(data);
> num1 = *(float*) ( &data1);
> --------------------------
>
> This works for me; always has!
> Now, mind you, I have done scientific coding.
> And in an enviroment with extremley well-behaved floats,
> where round-off has never been an issue.
> And very little exceptions....
>
> So...
>
> Why does my simpler implementation work?
> What problems could it cause?
> Friends have advised me to use Jorgensen, but I do not see the need.
> (I also have not gotten it to work)

Well, networking, ntohl(), htonl(), and so on are not part of the
C standard, so their details would be off-topic here.

However...

You are assuming that float is 32 bits. You are assuming that both
platforms store floats with the same bit representation. You are
assuming that swapping the bytes in the 32-bit int to go from one
platform to the other will be the same byte swapping that would be
needed for a 32-bit float.

There are probably some other assumptions being made as well, but
those are the ones that come to mind right away.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:ThisIsA...@gmail.com>

joblack

unread,
Aug 2, 2008, 1:34:39 PM8/2/08
to
On Jul 24, 3:51 am, Tom Impelluso <impel...@attila.sdsu.edu> wrote:
> Hello,
>
> I am aware of the need for ntohl and htonl.
> But floats?
I know these macros for the linux kernel. In the linux kernel you
shouldn't use floats because these aren't saved on a task switch.
Anyway for network function you normally don't need floats anyway.

Dag-Erling Smørgrav

unread,
Aug 7, 2008, 4:02:04 PM8/7/08
to
joblack <tobias...@gmail.com> writes:

> Tom Impelluso <impel...@attila.sdsu.edu> wrote:
> > I am aware of the need for ntohl and htonl.
> > But floats?
> I know these macros for the linux kernel. In the linux kernel you
> shouldn't use floats because these aren't saved on a task switch.
> Anyway for network function you normally don't need floats anyway.

These macros are not specific to the Linux kernel. They are part of the
Berkely sockets API, which predates Linux by ten years.

If Linux did not save FPU context on task switch, no-one could use
floating-point at all, whether in the kernel or in userland.

Most kernels (not just Linux) avoid using the FPU because saving and
restoring FPU context would greatly increase the system call overhead.
Besides, floating-point is rarely if ever needed in a kernel; off-hand,
the only place I can think of where the FreeBSD kernel (I'm not as
familiar with Linux as I am with FreeBSD) would benefit from floating-
point is when calculating the load average.

The OP was not interested in using floats "for network function", but in
transporting floating-point numbers between systems with different
endianness. There is no good universal solution, but if both systems
use IEEE754 floating-point representation and if both systems use the
same endianness for float as they do for uint32_t, ntohl() / htonl()
should work.

DES
--
Dag-Erling Smørgrav - d...@des.no

0 new messages