Cast...always cast... 
Author Message
 Cast...always cast...

I ve built a UDP server which receive the raw byte of a double...So
8...with little indian format...
When I receive it...I put them into a char[8]...
Then, when i print them out on the screen...I cast the value pointed by
the char[8] into double...
But the value is not the same as the one sent...
    Any Idea of the problem ?
Should i better put byte by byte data in a double ?
If I do it what would be the function ?

Thanks a lot for your help...
    Cedric



Tue, 02 Nov 2004 17:39:42 GMT  
 Cast...always cast...

Quote:
> I ve built a UDP server which receive the raw byte of a double...So
> 8...with little indian format...

ITYM "little endian". Unless you've discovered some new fancy format
invented in India...

Quote:
> When I receive it...I put them into a char[8]...
> Then, when i print them out on the screen...I cast the value pointed by
> the char[8] into double...
> But the value is not the same as the one sent...
>     Any Idea of the problem ?

Most likely your server and your clients use different binary encodings
for doubles. The m{*filter*}of the story is, never assume any particular
binary encoding of a double.

Quote:
> Should i better put byte by byte data in a double ?
> If I do it what would be the function ?

What do you exactly mean by "casting the double into a char[8]"?
If you write:
double d;
char c[8];
c = (char[8])d;
then that will not even compile.
Do you mean something like this?
double d;
char (*c)[8];
*c = *(char (*)[8])&d;

Putting the double byte for byte into the char[8] array could be done
like this:
double d;
char c[8];
memcpy(c, &d, 8);
but that will cause implementation-defined behaviour.

Why do you need to transport doubles over UDP at all? If you are
absolutely required to do so, one idea might be to write the string
representation of the double with sprintf() to the UDP packet and then
convert it back with strtod().

--

| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.*-*-*.com/ ~palaste       W++ B OP+                     |
\----------------------------------------- Finland rules! ------------/
"You have moved your mouse, for these changes to take effect you must shut down
and restart your computer. Do you want to restart your computer now?"
   - Karri Kalpio



Tue, 02 Nov 2004 17:45:52 GMT  
 Cast...always cast...

Quote:

> I ve built a UDP server which receive the raw byte of a double...So
> 8...with little indian format...
> When I receive it...I put them into a char[8]...
> Then, when i print them out on the screen...I cast the value pointed by
> the char[8] into double...
> But the value is not the same as the one sent...
>     Any Idea of the problem ?
> Should i better put byte by byte data in a double ?
> If I do it what would be the function ?

This is off-topic, but it sounds as if you either have a heterogenous
distributed system or you do not pack or unpack the structure correctly.
  If you have a homogenous distribute system (i.e., equivalent hardware,
equivalent operating systems, and equivalent compilers), then the
problem is most likely to be with packing/unpacking of the structure.
Quote:

> Thanks a lot for your help...
>     Cedric



Tue, 02 Nov 2004 17:51:19 GMT  
 Cast...always cast...

Quote:
>I ve built a UDP server which receive the raw byte of a double...So
>8...with little indian format...
>When I receive it...I put them into a char[8]...
>Then, when i print them out on the screen...I cast the value pointed by
>the char[8] into double...

It's better to cast the address of the char array to a pointer to double.
But that's still not a proper solution, because the char array may not
be properly aligned for a double (unless it was dynamically allocated).

Quote:
>But the value is not the same as the one sent...

Obviously.

Quote:
>    Any Idea of the problem ?

You can't cast a whole array of char to a double and casting a single
of the array is not going to produce a meaningful value.

Quote:
>Should i better put byte by byte data in a double ?

Yes.

Quote:
>If I do it what would be the function ?

No function is needed at all:

    double x;
    unsigned char *p = (unsigned char *)&x;

Use p[] to put the characters received from the network into the double.
When you're done, x contains the value that was sent by the other side,
assuming that both sides use compatible representations for values of
type double.

Another solution is to use a union defined like this:

    union {
        double x;
        unsigned char c[sizeof(double)];
    } foo;

Use foo.c[] to store the bytes coming from the network and foo.x to
get the actual double value.

Dan
--
Dan Pop
DESY Zeuthen, RZ group



Tue, 02 Nov 2004 19:59:28 GMT  
 Cast...always cast...

Quote:

> I ve built a UDP server which receive the raw byte of a double...So
> 8...with little indian format...
> When I receive it...I put them into a char[8]...
> Then, when i print them out on the screen...I cast the value pointed by
> the char[8] into double...
> But the value is not the same as the one sent...
>     Any Idea of the problem ?
> Should i better put byte by byte data in a double ?
> If I do it what would be the function ?

Is the server receiving the raw bytes in ascending or descending
order? For example, on my machine the value 3.14159 is stored as
0xf01b866e. Are you receiving the bytes as 0xf0, 0x1b, 0x86, 0x6e? Does
your machine want them in that order?

I would creat a union with the char array and a double. Then once I figure
out what order the bytes are coming and which order I wanted them I would
populate the union using the array of char. After than I can reference the
double in the union.

All this assumes that the data you are receiving in in the same format as
the data your machine requires, e.g. IEEE 754. If the data being sent is
in one floating point format and the machine you are working on requires
another then a conversion routine would be needed as well.

---

"iqgbgxmdbjlgdv.lksrqek.n";char *strchr(const char *,int); while
(*i){j+=strchr(t,*i++)-t;j%=sizeof t-1;putchar(t[j]);}return 0;}



Tue, 02 Nov 2004 22:26:59 GMT  
 Cast...always cast...

Quote:

> I ve built a UDP server which receive the raw byte of a double...So
> 8...with little indian format...
> When I receive it...I put them into a char[8]...
> Then, when i print them out on the screen...I cast the value pointed by
> the char[8] into double...
> But the value is not the same as the one sent...
>     Any Idea of the problem ?
> Should i better put byte by byte data in a double ?
> If I do it what would be the function ?

> Thanks a lot for your help...
>     Cedric

If sending 16 bytes instead of 8 is alright with you here is some
encoding/decoding code with no loss of precision (this should work between
almost any computers although I have tried it only between
i386/HP-RISC/alpha):

#define DBL_PKT_SIZE 16
#define SCALE 31

int sock_put_double(double x,char *buffer){

    int n,sign;
    double y,z1,z2;
    unsigned int m1,m2;

    if(x<0){
        y=frexp(-x,&n);
        sign=-1;
    }else{
        y=frexp(x,&n);
        sign=1;
    }

    z1=ldexp(y,SCALE);
    m1=z1;
    z2=ldexp(z1-m1,SCALE);
    m2=z2;

    buffer[0]='d';
    buffer[1]=(sign==1) ? '+' : '-';
    *((unsigned int *)(buffer+4))=htonl(m1);
    *((unsigned int *)(buffer+8))=htonl(m2);

    if(n>0){
        buffer[2]='+';
        *((unsigned int *)(buffer+12))=htonl((unsigned int)  n);
    }else{
        buffer[2]='-';
        *((unsigned int *)(buffer+12))=htonl((unsigned int) -n);
    }
    buffer[3]='\0';

    return DBL_PKT_SIZE;

Quote:
}

static void sock_get_double(double *x_p,char *buffer){
    unsigned int m1,m2,n;
    double z1,z2,y,x;

    m1=ntohl(*((unsigned int *)(buffer+4)));
    m2=ntohl(*((unsigned int *)(buffer+8)));
    n=ntohl(*((unsigned int *)(buffer+12)));

    z1=m1;
    z2=ldexp((double) m2,-SCALE);
    y=ldexp(z1+z2,-SCALE);

    if(buffer[2]=='+'){
        x=ldexp(y, n);
    }else{
        x=ldexp(y,-n);
    }
    (*x_p)=x*((buffer[1]=='+') ? 1. : -1.);

Quote:
}

It's possible to get rid of the casts and XtoX calls. You can sqeeze the
whole thing a some more too.
HTH Tobias.


Tue, 02 Nov 2004 23:35:54 GMT  
 Cast...always cast...

[snip - converting char array to double using a union]> Another solution
is to use a union defined like this:

Quote:

>     union {
>         double x;
>         unsigned char c[sizeof(double)];
>     } foo;
> Use foo.c[] to store the bytes coming from the network and foo.x to
> get the actual double value.

Are you serious?

        david

--
If 91 were prime, it would be a counterexample to your conjecture.
    -- Bruce Wheeler



Wed, 03 Nov 2004 01:55:18 GMT  
 Cast...always cast...

Quote:


> [snip - converting char array to double using a union]> Another
solution
> is to use a union defined like this:

> >     union {
> >         double x;
> >         unsigned char c[sizeof(double)];
> >     } foo;

> > Use foo.c[] to store the bytes coming from the network and foo.x to
> > get the actual double value.

> Are you serious?

You snipped

"assuming that both sides use compatible representations for values of
type double."

which makes Dan's solution rather bulletproof. :-)

We could even have used a less strict restriction than this, since
endian-issues can be handled at run time. Also, since viritually all
implementations of interest to OP, use the IEEE 754 DP format, I
don't see your point here.

--
Tor <torust AT online DOT no>
"To this day, many C programmers believe that 'strong typing' just means
pounding extra {*filter*} the keyboard". PvdL



Wed, 03 Nov 2004 08:17:42 GMT  
 Cast...always cast...

Quote:
>It's possible to get rid of the casts and XtoX calls. You can sqeeze the
>whole thing a some more too.

i'd be tempted to reduce it to an sprintf and a strtod.  if binary transfer
were desired i'd prefer xdr.

--
bringing you boring signatures for 17 years



Wed, 03 Nov 2004 16:11:51 GMT  
 Cast...always cast...

Quote:

>>It's possible to get rid of the casts and XtoX calls. You can sqeeze the
>>whole thing a some more too.

> i'd be tempted to reduce it to an sprintf and a strtod.  

That's what I had before, but the printf/strtod conversion is much slower
than the encoding I used here and the resulting packets were bigger. Also,
there is always the danger of loosing precision.

Quote:
> if binary transfer were desired i'd prefer xdr.

I never heard about xdr although there is a man page for it on my system.
It looks interesting and I will read it, but If I had to recode I would
probably use MPI.
Tobias.


Sat, 06 Nov 2004 00:56:49 GMT  
 
 [ 10 post ] 

 Relevant Pages 

1. old style casts vs new style casts

2. casting of struct element void pointer casting

3. malloc: to cast or not to cast

4. to cast or not to cast?

5. Discarded Function Values (To Cast or Not to Cast)

6. When is a cast not a cast?

7. Need help with reinterpret_cast, a C-style cast or function-style cast

8. old style casts vs new style casts

9. Need help with reinterpret_cast, a C-style cast or function-style cast

10. CString cast to LPCTSTR cast error

11. Need help with reinterpret_cast, a C-style cast or function-style cast

12. CString cast to LPCTSTR cast error

 

 
Powered by phpBB® Forum Software