# Patches for Review

- Thread: https://externals.io/message/58568
- Original archive: https://news-web.php.net/php.internals/58568
- Started by Anthony Ferrara on 2012-03-04T13:29:49+00:00
- Messages: 6
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #58568 — Anthony Ferrara — 2012-03-04T13:29:49+00:00

URL: https://externals.io/message/58568#58568

Hey all,

I had messaged about these patches before, but with the 5.4 release
process happening I think it slipped through the cracks.  I have 3
patches that are ready for inclusion...

https://bugs.php.net/bug.php?id=60813
Adding a new `hash_pbkdf2()` function to allow for a C level
implementation of the PKCS5 recomended password key stretching
algorithm.

https://bugs.php.net/bug.php?id=60789
Bringing `pow()` inline with docs in that it will attempt to return an
integer (by casting one or more of the arguments to int) if possible.
This fixes a precision loss that can occur with float arguments that
are exactly integers on 64 bit platforms.

https://bugs.php.net/bug.php?id=60596
A little code-cleanup to remove a superfluous if statement in a switch
in the spl_offset_convert_to_long function...

If anyone can commit these, if I can be granted the Karma to commit
them. of if anyone can comment as to why they should not be committed,
that would be great.

Thanks,

Anthony

---

## #58570 — Gustavo Lopes — 2012-03-04T13:52:14+00:00

URL: https://externals.io/message/58568#58570 · In reply to: #58568

On Sun, 04 Mar 2012 14:29:49 +0100, Anthony Ferrara <ircmaxell@gmail.com>  
wrote:

> I had messaged about these patches before, but with the 5.4 release
> process happening I think it slipped through the cracks.  I have 3
> patches that are ready for inclusion...
> > […]
>
> https://bugs.php.net/bug.php?id=60789
> Bringing `pow()` inline with docs in that it will attempt to return an
> integer (by casting one or more of the arguments to int) if possible.
> This fixes a precision loss that can occur with float arguments that
> are exactly integers on 64 bit platforms.
>
> [...]

This doesn't seem right. It's overly clever. It's like saying that

4.0 + 1

should return int(5) and not float(5.). Or perhaps a closer analogy would  
be:

if we're in a 64-bit platform (only then can integers have a larger  
precision than doubles);
if one of the operands is exactly an integer;
if the other operand is a float exactly representable as an integer  
(perhaps a large power of 2), but its accuracy is negative (where accuracy  
is the 15.9546 - log10(abs(x)), or, informally, the effective number of  
digits to the right of the decimal point);
if the result of the sum is exactly representable as a 64-bit integer;
then return such integer.

It's easy to see these sort of tricks would have to be applied all over  
the place (additions, products, and all other mathematical operations).

In sum, I think the rule that if a mathematical operation involves a  
float, the result should be a float ought to be kept.

-- 
Gustavo Lopes

---

## #58571 — Pierre Joye — 2012-03-04T13:53:44+00:00

URL: https://externals.io/message/58568#58571 · In reply to: #58570

> In sum, I think the rule that if a mathematical operation involves a float,
> the result should be a float ought to be kept.

Yes, it is a must.

-- 
Pierre

@pierrejoye | http://blog.thepimp.net | http://www.libgd.org

---

## #58572 — Nikita Popov — 2012-03-04T13:55:29+00:00

URL: https://externals.io/message/58568#58572 · In reply to: #58568

> Hey all,
> [snip]
> https://bugs.php.net/bug.php?id=60596
> A little code-cleanup to remove a superfluous if statement in a switch
> in the spl_offset_convert_to_long function...
Applied in http://svn.php.net/viewvc/?view=revision&amp;revision=323863.

Nikita

---

## #58574 — Anthony Ferrara — 2012-03-04T14:02:23+00:00

URL: https://externals.io/message/58568#58574 · In reply to: #58571

> > […]
>
> Yes, it is a must.

Well, I'm not so sure about that.

If you look at the docs of `pow()`, it describes the return type as
"base raised to the power of exp. If the result can be represented as
integer it will be returned as type integer, else it will be returned
as type float.".

That's not the current behavior.  pow((float) 2, 1) returns float(2).
If you want to update the docs instead of the code, then that's fine.

However, this can lead to precision loss in a number of cases (like
pow(2, (float) 55) which is not representable exactly by a float, and
hence cause data-loss.  Whereas converting to an integer allows (on 64
bit platforms) an exact representation.

I'm not suggesting changing addition to follow these rules, but to
bring `pow()` into alignment with the documentation.  And I think
because of the nature of `pow()`, the likelihood that you'll have
precision loss is a lot higher than other areas...

But if the sentiment is strong against it, then an update of docs is in order...

Additionally, I thought the whole point of type juggling in PHP was
such that the type didn't matter?  So that a float and an int are the
same from a usage standpoint?  But this is a case where the exact same
input (just type is different) leads to different output.  Which I
believe is inconsistent and incorrect.

But if the consensus is otherwise, that's fine...

Anthony

---

## #58580 — Gustavo Lopes — 2012-03-04T15:29:30+00:00

URL: https://externals.io/message/58568#58580 · In reply to: #58574

On Sun, 04 Mar 2012 15:02:23 +0100, Anthony Ferrara <ircmaxell@gmail.com>  
wrote:

> > […]
>
> Well, I'm not so sure about that.
>
> If you look at the docs of `pow()`, it describes the return type as
> "base raised to the power of exp. If the result can be represented as
> integer it will be returned as type integer, else it will be returned
> as type float.".
>
> That's not the current behavior.  pow((float) 2, 1) returns float(2).
> If you want to update the docs instead of the code, then that's fine.

You're reading too much into the documentation. The intention of that  
phrase seems to be if the result overflows, it will a float instead (just  
like when you add two large integers, for instance).

Yes, the plain text doesn't preclude your interpretation, but it's not  
supported by the implementation or the general behavior of mathematical  
operators in PHP. By all means, change it in order to make it more clear.

> However, this can lead to precision loss in a number of cases (like
> pow(2, (float) 55) which is not representable exactly by a float, and
> hence cause data-loss.  Whereas converting to an integer allows (on 64
> bit platforms) an exact representation.

You're making a critical error here. float(55.) is in fact different from  
int(55). Float values have a rounding error associated, while integers  
don't. The accuracy of float(55.) is 14.2142, which means the uncertainty  
is 6.10623*10^-15, or that float(55.) = 55 +- 3.05311*10^-15.

Mathematical operations will only increase the (relative) error and  
therefore decrease the precision. This is an example with Mathematica's  
arbitrary precision numbers (NOT machine precision numbers, even though  
I'm setting the arbitrary precision to $MachinePrecision); this keeps  
track of the accumulated errors:


In[30]:= SetPrecision[55, $MachinePrecision] // Precision
Out[30]= 15.9546
In[31]:= 2^SetPrecision[55, $MachinePrecision] // Precision
Out[31]= 14.3734

This means that if you do 2^55., the result will have total uncertainty:

In[34]:= 2^SetPrecision[55, $MachinePrecision] // 10^-Accuracy[#] &
Out[34]= 152.492

Take your example:

var_dump((int) (pow(2, (float) 55) - 1));

You're adding 1 to a result that has a total uncertainty of more than  
152... It's pointless, don't you think?

Of course, PHP doesn't keep track of errors, and the reason subtracting 1  
has no effect is because the rounding error itself in the result is  
already larger than 2:

In[45]:= 2^55. // 10^-Accuracy[#] &
Out[45]= 4.

> [...]
> Additionally, I thought the whole point of type juggling in PHP was
> such that the type didn't matter?  So that a float and an int are the
> same from a usage standpoint?

This is a very vague statement. "Doesn't matter" for what? We have  
different types for integers and floats, 1. and 1 are different things and  
this is reflected in several places. What type juggling does is that one  
*one specific type is expected*, but another one is given, PHP tries to  
convert the result. This doesn't mean the types are "implementation  
details".

> But this is a case where the exact same
> input (just type is different) leads to different output.  Which I
> believe is inconsistent and incorrect.
>
> But if the consensus is otherwise, that's fine...
>

-- 
Gustavo Lopes
