[muscle] Re: Byte-swapping functions

  • From: Jeremy Friesner <jeremyf@xxxxxxxxxxxxxx>
  • To: "muscle@xxxxxxxxxxxxx" <muscle@xxxxxxxxxxxxx>
  • Date: Mon, 23 Sep 2013 14:34:30 +0000

Hi Raymond,

I think the problem is that you are storing the big-endian values as doubles.  
Doing that is unreliable, because some floating point hardware (e.g. x86) will 
detect when a double value is invalid (aka NaN) and automatically change its 
bits to the canonical NaN bit-pattern, causing data loss which becomes apparent 
after you byte-swap the value back to native-endian.

To fix the problem in your example, you should change the type of your 
aUnFlattened and bUnFlattened variables from double to uint64 (or uint32 in 
cases where you use B_HOST_TO_LENDIAN_FLOAT).  If after that change, things 
still don't seem to be behaving correctly, let me know.

Cheers,
Jeremy

ps I fixed the dates on the web page, thanks :)

On Sep 23, 2013, at 6:13 AM, Raymond Dahlberg 
<rd@xxxxxxxxxxx<mailto:rd@xxxxxxxxxxx>>
 wrote:

Hi muscle-list!

We are using MUSCLE to send flattened C++ objects. Each object has a flatten() 
and unFlatten() method where each variable in the message are flattened and 
unflattened with the byte-swapping functions in MuscleSupport.h.

Back in 2007 when we upgraded to MUSCLE 3.30, we had to change all double 
variables to be flattened with the B_HOST_TO_LENDIAN_IDOUBLE function. We then 
got a problem that negative double values would become 0.0 when unflattened on 
the other side (after a flatten unflatten roundtrip). At the time we just 
worked around it by relying on the fact that we were only on little endian 
platforms, so we just did not use the byte swapping.

Now we are trying to catch up with recent versions of MUSCLE *, and this 
problem has surfaced again.

Example code:

    double a = 99.9;
    double b = -99.9;

    double aFlattened = B_HOST_TO_LENDIAN_IDOUBLE(a);
    double bFlattened = B_HOST_TO_LENDIAN_IDOUBLE(b);

    double aUnFlattened = B_LENDIAN_TO_HOST_IDOUBLE(aFlattened);
    double bUnFlattened = B_LENDIAN_TO_HOST_IDOUBLE(bFlattened);

    cout << "Original values, one positive and one negative:" << endl;
    cout << "===============================================" << endl;
    cout << "a: " << a << endl;
    cout << "b: " << b << endl << endl;

    cout << "Values flattened:" << endl;
    cout << "================" << endl;
    cout << "aFlattened: " << aFlattened << endl;
    cout << "bFlattened: " << bFlattened << endl << endl;

    cout << "Values unflattened back to original:" << endl;
    cout << "===================================" << endl;
    cout << "aUnFlattened: " << aUnFlattened << endl;
    cout << "bUnFlattened: " << bUnFlattened << endl;

Output:

    Original values, one positive and one negative:
    ===============================================
    a: 99.9
    b: -99.9

    Values flattened:
    ================
    aFlattened: 4.63673e+018
    bFlattened: 1.38601e+019

    Values unflattened back to original:
    ===================================
    aUnFlattened: 99.9
    bUnFlattened: -0

This shows that the bUnFlattened variable is set to -0.0, while I was expecting 
it to be -99.9 as the original b variable.

Now, as my college Lars Magne noticed, if we change the following in 
MuscleSupport.h:

#  define B_HOST_TO_LENDIAN_INT64(arg)  ((uint64)(arg))
#  define B_LENDIAN_TO_HOST_INT64(arg)  ((uint64)(arg))

to use int64 instead of uint64 it seem to work as expected, with this in 
MuscleSupport.h:

#  define B_HOST_TO_LENDIAN_INT64(arg)  ((int64)(arg))
#  define B_LENDIAN_TO_HOST_INT64(arg)  ((int64)(arg))

we get the following output:

    Original values, one positive and one negative:
    ===============================================
    a: 99.9
    b: -99.9

    Values flattened:
    ================
    aFlattened: 4.63673e+018
    bFlattened: -4.58664e+018

    Values unflattened back to original:
    ===================================
    aUnFlattened: 99.9
    bUnFlattened: -99.9

The testing is done on Windows 7 x64, with MSVC 2010 32bit.

So, - are we using it wrong, - or is this a bug in the byte swapping functions?

*) One minor thing, - the release date of the latest version (5.92) on the web 
page seem to be wrong (in the future :).

Best regards,
Raymond Dahlberg


NOTICE: This email may contain confidential information.  Please see 
http://www.meyersound.com/confidential/ for our complete policy.

Other related posts: