in reply to Binary conversion
Oddly enough I had almost exactly the same problem a couple of days ago. I kept feeling that there must be a way to combine pack and unpack but I couldn't get anything to work.
In the end I decided to get back to fundimentals, and work out what the bits looked like
# This is from memory so may not work $binary_struct = read_from_somewhere(); $was_bits = unpack("b64",$binary_struct); $now_bits = shuffle_bits($was_bits); $float_val = unpack("d",pack("b64",$now_bits));
This is not particularly elegant but it does let you play with different combinations of reversing bytes, whole sequences or doing other strange combinations. In the debugger try $v = unpack("b64",2.5) (and a few other values) to see what your machine does and compare that with what you get from the file. This is the actual routine I used (you input data is probably not in the same byte order so you will have to play with the $binary2double_fun a bit.
sub deduce_endian { my($v); # Deduce the machine's native FP format by encoding the # number 2.5 as a bit string. Once we know how to get # from doubles to bit strings we can deduce the function # for doing the reverse from our binary data $v = unpack("b64",pack("d",2.5)); if($v eq "0000000000000000000000000000000000000000000000000010000000000010" ) { # Intel or something like it $endian = "ieee-little"; $binary2double_fun = sub { # We have to reverse the bitstring my $bits = reverse(shift); # Then map to floats return(unpack("d",pack("b64",$bits))); }; } elsif($v eq "0000001000100000000000000000000000000000000000000000000000000000" ) { # *NIX hardware $endian = "ieee-big"; $binary2double_fun = sub { # a combination of pack and unpack will do it my $bits = shift; my $res; while($bits) { $res .= reverse(substr($bits,0,8)); $bits = substr($bits,8); } return(unpack("d",pack("b64",$res))); }; } else { print STDERR "Not configured for this machine yet\n"; exit(20); } } # Then I called it like this # Read from the file $out = hex2binary($in); # Then map this to our double representation deduce_endian() if(!$endian); return &{$binary2double_fun}($out) if($binary2double_fun);
The only difference I had (as you can see) is that I was using 8 byte floats rather than 4 (IEEE format). I am sure that there is a better way to do this but I just wanted to get it working.
|
|---|