in reply to Re^2: Mysteries of unpack("a", ...)
in thread Mysteries of unpack("a", ...)

I don't know why you're dividing the fraction part by 0xFF_FFFF, if you want to do it that way you'd surely want to divide by 0x100_0000.

The following:

my $f = unpack('N', pack('B32', "01000010001111000000000000000000")) +; printf "0x%08X = %12.9f\n", $f, conv_HFP($f) ; sub conv_HFP { my ($f) = @_ ; my $s = ($f & 0x8000_0000) ? -1 : +1 ; my $e = (((($f >> 24) & 0x7F) - 0x40) * 4) - 24 ; return $s * ($f & 0xFF_FFFF) * (2 ** $e) ; } ;
will convert 4 byte 360/370 style radix 16 floats (where b31 is sign, b30..b24 is exponent biased by 0x40, and b23..0 is the fraction with binary point to the left of b23). Using the one example I can see the result is:
  0x423C0000 = 60.000000000
From a quick poke around, it appears that floats are stored big-endian.

I note that you say these are "IBM 390 E format 4 byte floats". The ESA/390 supports both the old 360/370 HFP (hex floating point) and new newer BFP (binary floating point) which conforms to IEEE 754-1985. Converting BFP can be done so:

my $f = unpack('N', pack('B32', "01000010001111000000000000000000")) +; printf "0x%08X = %12.9f\n", $f, conv_BFP($f) ; sub conv_BFP { my ($f) = @_ ; my $s = ($f & 0x8000_0000) ? -1 : +1 ; my $e = ((($f >> 23) & 0xFF) - 0x7F) - 23 ; return $s * (($f & 0x7F_FFFF) | 0x80_0000) * (2 ** $e) ; } ;
in the unlikely event your native floating point is not IEEE 754-1985 !! (Otherwise unpack('f', ...), with suitable care over the byte ordering !)