Doc #52729 [Opn->Bgs]: unpack() format I, L, N and V returns negative value
| From: | cataphract@php.net | Date: | Sun, 05 Sep 2010 10:00:38 +0000 |
| Subject: | Doc #52729 [Opn->Bgs]: unpack() format I, L, N and V returns negative value | ||
| References: | 1 | Groups: | php.doc.bugs |
| Request: | Send a blank email to doc-bugs+get-4977@lists.php.net to get a copy of this message | ||
Edit report at http://bugs.php.net/bug.php?id=52729&edit=1
ID: 52729
Updated by: cataphract@php.net
Reported by: hiroaki dot kawai at gmail dot com
Summary: unpack() format I, L, N and V returns negative value
-Status: Open
+Status: Bogus
Type: Documentation Problem
Package: Unknown/Other Function
Operating System: Linux
PHP Version: 5.3.3
Block user comment: N
New Comment:
I'm closing this as bogus because this is documented behavior of unpack.
However, see http://svn.php.net/viewvc/?view=revision&revision=303052
Previous Comments:
------------------------------------------------------------------------
[2010-09-05 11:59:09] cataphract@php.net
Automatic comment from SVN on behalf of cataphract
Revision: http://svn.php.net/viewvc/?view=revision&revision=303052
Log: - Expanding on the large integers values and unsigned types.
Tangentially related to bug #52729.
------------------------------------------------------------------------
[2010-09-04 11:41:53] cataphract@php.net
Read: in that range to create PHP integers with an appropriate negative
number.
------------------------------------------------------------------------
[2010-09-04 11:40:00] cataphract@php.net
OK, this is documented. The docs for unpack say:
> Note that PHP internally stores integral values as signed. If you
unpack a large unsigned long and it is of the same size as PHP
internally stored values the result will be a negative number even
though unsigned unpacking was specified.
So this paragraph in pack:
> Also note that PHP internally stores integer values as signed values
of a machine-dependent size. If you give it an unsigned integer value
too large to be stored that way it is converted to a float which often
yields an undesired result.
only means the internal representation of large integers may be with PHP
floats and that packing those floats may yield undesired results.
This isn't a valid concern for machines with 32-bit longs. If longs are
32-bit, pack doesn't make available any mode for 64-bit longs. Numbers
bigger than 2^32-1 could never be handled anyway, so the only problem is
that numbers between 2^31 and 2^32-1 are represented with PHP floats
instead of PHP ints. However, pack arguments that are PHP floats are
converted to PHP integers before packing (with a triple cast (long)
(unsigned long) (long long)), and, given the usual 52-bit mantissa for
doubles allows the integers in this range to be stored without precision
loss, this yields the expected memory representation.
If longs are 64-bit long, then it's another matter. The floats' mantissa
is not long enough to store without precision loss numbers between 2^63
and 2^64-1, so the only way to pack numbers in those range to create PHP
floats with an appropriate negative number.
------------------------------------------------------------------------
[2010-08-30 08:12:46] hiroaki dot kawai at gmail dot com
For bitwise operation, I see the problem, current implementation is so
confusing.
------------------------------------------------------------------------
[2010-08-30 02:38:08] cataphract@php.net
That's because when you do
pack("I",4294967295)
the float(4294967295) is cast into an int before the conversion. Notice
(x86):
$ php -r 'var_dump((int)4294967295);'
int(-1)
So you're actually packing int(-1) as unsigned. It seems reasonable that
you receive a int(-1) back when you unpack it. Returning a float has
several problems: performance, bitwise operators may not work as
expected etc.
Like I said, the signed/unsigned is only relevant when you may have to
move the sign bit.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
http://bugs.php.net/bug.php?id=52729
--
Edit this bug report at http://bugs.php.net/bug.php?id=52729&edit=1