Re: Change default serialize precision from 100 to 17
| From: | Ilia Alshanetsky | Date: | Tue, 08 Feb 2011 12:55:41 +0000 |
| Subject: | Re: Change default serialize precision from 100 to 17 | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-51433@lists.php.net to get a copy of this message | ||
+1
On Mon, Feb 7, 2011 at 8:26 PM, Gustavo Lopes <glopes@nebm.ist.utl.pt> wrote:
> The default serialize precision is currently [1] set at 100. A little code
> inspection shows precision, in this case, takes the usual meaning of number
> of significant digits.
>
> Given that the implicit precision of a (normal) IEEE 754 double precision
> number is slightly less than 16 digits [2], this is a serious overkill. Put
> another way, while the mantissa is composed of 52 bits plus 1 implicit bit,
> 100 decimal digits can carry up to 100*log2(10) =~ 332 bits of information,
> around 6 times more.
>
> Given this, I propose changing the default precision to 17 (while the
> precision is slightly less than 16, a 17th digit is necessary because the
> first decimal digit carries little information when it is low).
>
> From my tests, this makes serialization and unserialization of doubles
> around 3 times faster (counting the function calls to serialize/unserialize,
> plus a loop variable increment and stop condition check). It also makes the
> serialization data.
>
> Crucially, from my tests, the condition that the variable stays the same
> before and after serialization+unserialization still holds. The test
> include, for little endian machines, verifies this.
>
> If no one objects, I'll change the default precision to 17.
>
> //run with php -d serialize_precision=17
> $numbers = array(
> "0000000000000000", //0
> "2d431cebe2362a3f", //.0002
> "2e431cebe2362a3f", //.0002 + 10^-Accuracy[.0002]*1.01
> "0000000000001000", //2^-1022. (minimum normal double)
> "0100000000001000", //2^-1022. + 10^-Accuracy[2^-1022.]*1.01
> "ffffffffffffef7f", //2^1024. (maximum normal double)
> "feffffffffffef7f", //2^1024. - 10^-Accuracy[2^1024.]
> "0100000000000000", //minumum subnormal double
> "0200000000000000", //2nd minumum subnormal double
> "fffffffffffff000", //maximum subnormal double
> "fefffffffffff000", //2nd maximum subnormal double
> "0000000000000f7f", //+inf
> "0000000000000fff", //-inf
> );
>
> foreach ($numbers as $ns) {
> $num = unpack("d", pack("H*", $ns)); $num = reset($num);
> echo "number: ", sprintf("%.17e", $num), "... ";
> $num2 = unserialize(serialize($num));
> $repr = unpack("H*", pack("d", $num2)); $repr = reset($repr);
> if ($repr == $ns)
> echo "OK\n";
> else
> echo "mismatch\n\twas: $ns\n\tbecame: $repr\n";
> }
>
>
> [1]:
> http://lxr.php.net/opengrok/xref/PHP_TRUNK/main/main.c#451
> [2]:
> http://en.wikipedia.org/wiki/Double_precision_floating-point_format
> --
> Gustavo Lopes
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>