[muscle] Byte-swapping functions

  • From: Raymond Dahlberg <rd@xxxxxxxxxxx>
  • To: muscle@xxxxxxxxxxxxx
  • Date: Mon, 23 Sep 2013 15:13:52 +0200

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

Other related posts: