Hi Marc,

On Sat, Oct 14, 2023 at 1:21 AM Marc Bennewitz <marc@mabe.berlin> wrote:

> Hi Jakub,
>
> On 13.10.23 13:25, Jakub Zelenka wrote:
> > On Tue, Sep 26, 2023 at 11:39 AM Marc Bennewitz <marc@mabe.berlin>
> wrote:
> >
> >> Hi internals
> >>
> >> I'd like to put a new RFC under discussion:
> >> https://wiki.php.net/rfc/integer-rounding
> >>
> >>
> > I would personally prefer a new function for rounding integers if anyone
> > wants to round large integers.
> >
> > The things is that the current round behaviour is consistent with a way
> how
> > floats to int conversion is done for strict types.
> >
> > <?php
> > declare(strict_types=1);
> >
> > function test(float $a) {
> >      echo $a;
> > }
> > test(987654321098765432);
> >
> >
> > So it won't really help that much if this function returns long for long
> in
> > cases where the result is passed to another function expecting float.
> >
> > The main problem that I see with the current approach is that it changes
> > return type for an edge case that most people are not impacted with. For
> > example it is quite usual that people had a float value with 0 fraction
> > which gets json encode to int. When they decode it and use round, the
> > return type is suddenly int. Even though it's usually not a problem,
> there
> > might be some code that expects float and maybe even assert that with
> > is_float. Such code will break.
> >
> > On the other hand I see use some case for rounding large integers with
> > negative precision. But for that to work I think it would be better to
> have
> > a special function.
>
> Your JSON example is a bit unrelated because if you care about your
> types your should have used JSON_RESERVE_ZERO_FRACTION in the first
> place else you should not care about int vs float at all.
>
>
The thing is that JSON might be encoded by another application that doesn't
care about types that much. In fact in JSON there is no difference between
2.0 and 2. So this is quite possible situation IMHO.


> It's true that passing/returning int to/from a function expecting float
> will cast but currently with these rounding functions it's a different
> deal as they expect an `int|float` instead of just `float`. So it's not
> cast on passing the argument but the functions itself are casting.
>
>
Well internally yeah but effectively it is a cast on the return type. What
I meant is that this wont help everywhere when it's passed to function
expecting just float unless it is changed by user to accept int|float.

Where another set of functions would avoid the BC break it also would be
> against having PHP as a loosely typed languageputting the burden to
> everyone caring. I already see hundreds of `is_int($v) ? round_int($v) :
> round($v)` everywhere around.
>
>
But for me it's sort of an edge as I would think it is not that usual
rounding values that are greater than 2^53. I think it would be good to
note in the RFC what other language do about this issue. I quickly checked
Go and it seems to only have float64 rounding (Math.Round). Rust seems to
also round just f64.

I'm starting to feel that the problem is that the input type is defined as
int|float. I think we should just correct it to float.

Regards

Jakub

Reply via email to