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

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to