Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:57413 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 60554 invoked from network); 18 Jan 2012 13:11:25 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 18 Jan 2012 13:11:25 -0000 Authentication-Results: pb1.pair.com smtp.mail=ircmaxell@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=ircmaxell@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.216.49 as permitted sender) X-PHP-List-Original-Sender: ircmaxell@gmail.com X-Host-Fingerprint: 209.85.216.49 mail-qw0-f49.google.com Received: from [209.85.216.49] ([209.85.216.49:39385] helo=mail-qw0-f49.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 1C/F0-55749-BF4C61F4 for ; Wed, 18 Jan 2012 08:11:23 -0500 Received: by qadc14 with SMTP id c14so1716518qad.8 for ; Wed, 18 Jan 2012 05:11:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type; bh=sp3ShtYnl+mEqB45w5zKyeXaPhUaxCHmptk8p1PBl1o=; b=RqOX3rVvYPjVJ8IkX5MEGypX90umL1vw8yExw/5UWhMhnGAqG/LOgKv4Vh1FxtSkI/ Rk4fflf0lbD73YLemCwwJYE8qBPxzPRz2ES8ft98XYfeMKgkdjNHydxWJb/eZqOG7zVq YXi1I0PDxhrJabxaUyZWzErTANzgG2rOlFuco= MIME-Version: 1.0 Received: by 10.224.33.11 with SMTP id f11mr947138qad.76.1326892280788; Wed, 18 Jan 2012 05:11:20 -0800 (PST) Received: by 10.229.73.201 with HTTP; Wed, 18 Jan 2012 05:11:20 -0800 (PST) Date: Wed, 18 Jan 2012 08:11:20 -0500 Message-ID: To: internals@lists.php.net Content-Type: text/plain; charset=ISO-8859-1 Subject: [Req 60789][Patch] Pow using floats when one argument is a float From: ircmaxell@gmail.com (Anthony Ferrara) Hey all, I've found what I would call a bug (I submitted it as a feature request, since that's probably more appropriate) with pow(). If any one of the arguments is a float, it will cause the result to be a float. On 32 bit systems this is fine, since all integers can be exactly specified by the double precision float. But on 64 bit systems, this can cause a loss of precision since only numbers up to 2^54-1 can be exactly represented. This actually caused me to have to cast certain calls to ints to get them to behave correctly (as in this line: https://github.com/ircmaxell/PHP-CryptLib/blob/master/lib/CryptLib/Random/Generator.php#L111 ). I've attached a patch which checks to see if both arguments can be exactly represented by a long integer, and if so converts both to a long, allowing a long to be returned. If either one of the arguments is unrepresentable as a long (ex: 1.5), it will fallback on doing the operation as a double (as it would now). Additionally, while testing the patch, I found a tested-for-bug in the 64 bit test cases: pow(-9.2233720368548E+18, 9223372036854775807) == INF Clearly, that should be -INF due to the negative base and odd exponent. But with the current code the odd portion of the exponent is lost in the conversion to double (since it can't be representable), and the exponent becomes even. This patch changes that, since the base is exactly representable as a long int, the power is done via the alternative algorithm. https://bugs.php.net/bug.php?id=60789 What are your thoughts? Thanks, Anthony