mjscott2702 has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to generate some binary data on an x86 box (i.e little-endian) that emulates generating that data on a Sun box (i.e. big-endian). I can get most of the integer fields (various byte-lengths) to format correctly using pack. However, I have hit a brick-wall for floating point values (float not double).

I think my problem lies here (from the pack documentation): "f A single-precision float in the native format."

My guess is that the key phrase there is native format.

So, is there a way of generating a float in "non-native" format to look like it comes from a big-endian CPU? I tried simply reversing the bytes, but that didn't work:

reverse pack("f", $floatVal)

Any ideas most welcome!

Replies are listed 'Best First'.
Re: Use pack to create a float in non-native format
by BrowserUk (Patriarch) on Feb 06, 2010 at 18:52 UTC

    A guess based upon my reading of Table 2.5 and the preceding paragraph. I've no way to check it.

    $SPARCfloat = pack 'a4a4', reverse unpack 'a4a4', pack 'f', 1222222345 +.678e9;;

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Well, I tried it (actually needed single-format floats i.e. 32-bits, so adjusted accordingly) - my guess is that the bits were reversed from what they needed to be. Which brings me on to the next response...

        I didn't think to try the built-in big-endian conversion, because you said you'd already tried reversing the bytes. And that's all it does.

        I missed that you'd forgotten the scalar context requirement:

        print unpack 'H*', pack 'f>', 123.456;; 42f6e979 print unpack 'H*', scalar reverse pack 'f', 123.456;; 42f6e979

        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Use pack to create a float in non-native format
by rowdog (Curate) on Feb 07, 2010 at 01:19 UTC

    perldoc -f pack says

    All integer and floating point formats as well as p and P and () -groups may be followed by the > or < modifiers to force big- or little- endian byte-order, respectively. This is especially useful, since n , N , v and V don't cover signed integers, 64-bit integers and floating point values. However, there are some things to keep in mind.
    but take note of
    Forcing big- or little-endian byte-order on floating point values for data exchange can only work if all platforms are using the same binary representation (e.g. IEEE floating point format). Even if all platforms are using IEEE, there may be subtle differences. Being able to use > or < on floating point values can be very useful, but also very dangerous if you don't know exactly what you're doing. It is definitely not a general way to portably store floating point values.

      That was what I needed (teach me to read the manpages all the way down). Since the binary structure I am creating contains a field specifying the endianess of the data, simply doing something like

      print pack 'f>', 1.2345;

      worked like a charm. Thanks to all for the responses.