Perl strange behaviour on unpack of floating value
Asked Answered
A

2

6

I have this snippet with a strange result (279.1... vs. 279.6...):

$ perl -e "print unpack('f>', pack ('f>', 279.117156982422));"
279.617156982422

While this one works

$ perl -e "print unpack('f>', pack ('f>', 279.117256982422));"
279.117248535156

And those ones as well

$ perl -e "print unpack('f<', pack ('f<', 279.117156982422));"
279.11715698242

$ perl -e "print unpack('f', pack ('f', 279.117156982422));"
279.117156982422

What's wrong? Is that a bug in unpacking of non-native endian floating point values?

Note Perl is version 5.14.2 under Cygwin on a PC.

Attrahent answered 23/9, 2013 at 22:7 Comment(11)
Are the first two cases run with different versions of perl or different operating systems?Nickelplate
What's the result of pack in the first case (I mean, what are the bytecodes)?Fulminous
Reproducible here with 5.14.2 (on Cygwin on Win7x64). Curious. You may have found a bug. Note that print unpack('H8', pack ('f>', 279.117156982422)) to get at the bits returns 438b8eff, which is the correct bit pattern according to this siteMidpoint
However, NOT reproducible on 5.10.2 on RHEL 6.1Midpoint
Reproduced on perl v5.14.2 on Linux too.Dunnage
Thanks for your comments. I tried on different versions of Perl on Linux (but not V5.14.2) and Windows (Strawberry V5.16.2). Works on them...Attrahent
@XuDing Anything special about your Linux? Is it a 32bit system?Rabelaisian
@SlavenRezic Yes, 32bit Ubuntu 12.10, Linux version 3.5.0-26-generic (buildd@akateko) (gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1)Dunnage
@XuDing Can you try cpan -t Acme::Study::SREZIC and see if it fails on your system?Rabelaisian
Reproduced on a Windows 8.1 system, see cpantesters.org/cpan/report/…Rabelaisian
I got the correct result using Strawberry Perl, Perl version 5.18.2 (compiled 2014-01-07).Convolvulaceous
H
1

This is a GCC problem.

cpan -t Acme::Study::SREZIC passes OK on my 32bit systems where the Perl binary is compiled with GCC 4.5.4 or 4.6.3 or 4.6.4 and does not pass on systems where the Perl binary is compiled with GCC 4.7.3 or 4.8.3

Hidalgo answered 25/11, 2014 at 1:5 Comment(0)
S
1

Definitely a bug in Perl's unpacking. It has difficulty in handling floats in the binary form xxxxyyFF at least in a 32-bit platform, where 80 <= yy <= BF. The packed result will become xxxxzzFF, where zz = yy + 40 (all in hexadecimal). And this is not a problem of endianness, as you could see here:

$ perl -e "print unpack('H8', pack ('f', unpack('f', pack('H8', '000088ff'))));"; 
0000c8ff
Supine answered 16/10, 2013 at 13:33 Comment(1)
I wrote a bug report on rt.perl.org: rt.perl.org/Ticket/Display.html?id=120405Rabelaisian
H
1

This is a GCC problem.

cpan -t Acme::Study::SREZIC passes OK on my 32bit systems where the Perl binary is compiled with GCC 4.5.4 or 4.6.3 or 4.6.4 and does not pass on systems where the Perl binary is compiled with GCC 4.7.3 or 4.8.3

Hidalgo answered 25/11, 2014 at 1:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.