Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:51432 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 77779 invoked from network); 8 Feb 2011 01:26:17 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 8 Feb 2011 01:26:17 -0000 Authentication-Results: pb1.pair.com header.from=glopes@nebm.ist.utl.pt; sender-id=unknown Authentication-Results: pb1.pair.com smtp.mail=glopes@nebm.ist.utl.pt; spf=permerror; sender-id=unknown Received-SPF: error (pb1.pair.com: domain nebm.ist.utl.pt from 193.136.128.21 cause and error) X-PHP-List-Original-Sender: glopes@nebm.ist.utl.pt X-Host-Fingerprint: 193.136.128.21 smtp1.ist.utl.pt Linux 2.6 Received: from [193.136.128.21] ([193.136.128.21:47095] helo=smtp1.ist.utl.pt) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id C0/63-53329-5BB905D4 for ; Mon, 07 Feb 2011 20:26:14 -0500 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp1.ist.utl.pt (Postfix) with ESMTP id 7DBD47000443 for ; Tue, 8 Feb 2011 01:26:10 +0000 (WET) X-Virus-Scanned: by amavisd-new-2.6.4 (20090625) (Debian) at ist.utl.pt Received: from smtp1.ist.utl.pt ([127.0.0.1]) by localhost (smtp1.ist.utl.pt [127.0.0.1]) (amavisd-new, port 10025) with LMTP id Vk7yxB9K5zML for ; Tue, 8 Feb 2011 01:26:10 +0000 (WET) Received: from mail2.ist.utl.pt (mail.ist.utl.pt [IPv6:2001:690:2100:1::8]) by smtp1.ist.utl.pt (Postfix) with ESMTP id 332F07000428 for ; Tue, 8 Feb 2011 01:26:10 +0000 (WET) Received: from damnation (91.80.136.95.rev.vodafone.pt [95.136.80.91]) (Authenticated sender: ist155741) by mail2.ist.utl.pt (Postfix) with ESMTPSA id EB8102005410 for ; Tue, 8 Feb 2011 01:26:09 +0000 (WET) Content-Type: text/plain; charset=utf-8; format=flowed; delsp=yes To: "internals@lists.php.net" Date: Tue, 08 Feb 2011 01:26:09 -0000 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Organization: =?utf-8?Q?N=C3=BAcleo_de_Eng=2E_Biom=C3=A9di?= =?utf-8?Q?ca_do_I=2ES=2ET=2E?= Message-ID: User-Agent: Opera Mail/11.01 (Linux) Subject: Change default serialize precision from 100 to 17 From: glopes@nebm.ist.utl.pt ("Gustavo Lopes") 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