[RFC] intdiv()

php.internals

Andrew Faulds

12 years ago
Good evening again, PHP currently lacks a way to do integer division. You can floor or int cast a floating-point division, but beyond 53-bits that produces the wrong result: $ sapi/cli/php -r 'var_dump((int)(PHP_INT_MAX / 3));' int(3074457345618258432) Furthermore, using a floating-point division isn’t really a proper way to do it; it’s a workaround for a lack of language support for a quite basic operation. This RFC proposes a function for integer division, intdiv(). It would work properly with 64-bit values: $ sapi/cli/php -r 'var_dump(intdiv(PHP_INT_MAX, 3));' int(3074457345618258602) It works exactly as you’d expect it to. If you divide by zero, it does exactly the same thing the division operator does (E_WARNING and returns FALSE). While this is simple enough, I’m also considering possibly shortening it to div() (more likely to cause conflicts, but easier to type), implementing it as an internal function (à la pow()), and perhaps implementing it as an infix operator (3 div 2 === 1). The RFC is here: https://wiki.php.net/rfc/intdiv It elaborates a little more, so I’d suggest reading it first. What are your thoughts? I think this is a simple and obvious addition. Thanks!
-- Andrea Faulds http://ajf.me/

Stas Malyshev

12 years ago
Hi!
> It elaborates a little more, so I’d suggest reading it first. What > are your thoughts? I think this is a simple and obvious addition.
INT_MAX is kind of an edge case, if you need arbitrary-length precision you can always use gmp or bcmath. I'm not sure this one-off use case that is already covered by two extensions really needs another function. Practically, where would you need exact division up to 53 bits but not beyond?
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/

Andrew Faulds

12 years ago
On 15 Jul 2014, at 01:58, Stas Malyshev <smalyshev@sugarcrm.com> wrote:
> INT_MAX is kind of an edge case,
It’s just an obvious example, integers beyond 2^53 fulfill this.
> if you need arbitrary-length precision > you can always use gmp or bcmath.
I’m not asking for arbitrary-length precision, I’m asking for an integer division operator for PHP’s integer type. Granted, this function would be even more useful if my bigints RFC got in, but it’s useful now.
> I'm not sure this one-off use case > that is already covered by two extensions really needs another function.
Both of those are likely not to be installed on most systems. Why do you need to install gmp or bcmath to do a basic operation with two 64-bit integers yielding a 64-bit integer? Many languages support this (C, C++, C#, Java, Python, to name a few). Why shouldn’t PHP?
> Practically, where would you need exact division up to 53 bits but not > beyond?
No idea. This RFC isn’t proposing that.
-- Andrea Faulds http://ajf.me/

Stas Malyshev

12 years ago
Hi!
> Both of those are likely not to be installed on most systems. Why do
Why not? bcmath is in core since forever and has no external requirements, gmp builds practically everywhere too. AFAIR all distros have it.
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/

Kris Craig

12 years ago
On Mon, Jul 14, 2014 at 10:17 PM, Stas Malyshev <smalyshev@sugarcrm.com> wrote:
> Hi! > > > Both of those are likely not to be installed on most systems. Why do > > Why not? bcmath is in core since forever and has no external > requirements, gmp builds practically everywhere too. AFAIR all distros > have it. > -- > Stanislav Malyshev, Software Architect > SugarCRM: http://www.sugarcrm.com/ > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
While a practical argument can certainly be made that existing solutions can fit the examples OP cited, I don't think that takes away from the underlying principle of the argument: That there's no reason *not* to include a basic integer division in PHP. It's never made sense to me why it wasn't included. Rather than an intdiv() function, though, I wonder if an operator would be a better approach. Some languages I've seen that use / as the division operator will use a \ as the integer division operator. --Kris

Andrew Faulds

12 years ago
On 15 Jul 2014, at 06:50, Kris Craig <kris.craig@gmail.com> wrote:
> While a practical argument can certainly be made that existing solutions can fit the examples OP cited, I don't think that takes away from the underlying principle of the argument: That there's no reason *not* to include a basic integer division in PHP. It's never made sense to me why it wasn't included. Rather than an intdiv() function, though, I wonder if an operator would be a better approach. Some languages I've seen that use / as the division operator will use a \ as the integer division operator.
We use \ for namespaces, and Python 3’s // obviously can’t be used, so I might suggest Pascal’s div operator: $minutes = ($s div 60) % 60; Failing that, div() as a built-in function much like pow() is: $minutes = div($s, 60) % 60;
-- Andrea Faulds http://ajf.me/

Kris Craig

12 years ago
On Tue, Jul 15, 2014 at 5:13 AM, Andrea Faulds <ajf@ajf.me> wrote:
> > On 15 Jul 2014, at 06:50, Kris Craig <kris.craig@gmail.com> wrote: > > > While a practical argument can certainly be made that existing solutions > can fit the examples OP cited, I don't think that takes away from the > underlying principle of the argument: That there's no reason *not* to > include a basic integer division in PHP. It's never made sense to me why > it wasn't included. Rather than an intdiv() function, though, I wonder if > an operator would be a better approach. Some languages I've seen that use > / as the division operator will use a \ as the integer division operator. > > We use \ for namespaces, and Python 3’s // obviously can’t be used, so I > might suggest Pascal’s div operator: >
Oh, derp. On Wed, Jul 16, 2014 at 5:11 PM, Bishop Bettini <bishop@php.net> wrote:
> As another contender, how about: > > $x = 242 %/ 7; > $x %/= 13; >
I like this idea! I haven't seen anyone else respond to it yet, though. My only question would be whether %/ or /% would be more appropriate. Perhaps the RFC could have two options for approval; one with %% and the other with either %/ or /%. Thoughts? --Kris

Zeev Suraski

12 years ago
> -----Original Message----- > From: Kris Craig [mailto:kris.craig@gmail.com] > Sent: Thursday, July 17, 2014 6:02 AM > To: Andrea Faulds > Cc: Stas Malyshev; PHP internals > Subject: Re: [PHP-DEV] [RFC] intdiv() > > On Tue, Jul 15, 2014 at 5:13 AM, Andrea Faulds <ajf@ajf.me> wrote: > Perhaps the RFC could have two options for approval; one with %% and the > other with either %/ or /%. Thoughts?
Yes, horrible ones :) I can't believe we're seriously considering adding an operator for something so uncommon. I'm actually in favor of adding APIs, but absolutely not an obscure operator. We're not Perl. Zeev

Lester Caine

12 years ago
On 15/07/14 06:17, Stas Malyshev wrote:
>> Both of those are likely not to be installed on most systems. Why do > Why not? bcmath is in core since forever and has no external > requirements, gmp builds practically everywhere too. AFAIR all distros > have it.
Taking this in isolation is wrong ... It is essentially linked up with all of the discussion on '64bit' processing. What seems to be ignored so far is the simple 'bigint' value. Limiting 32 bit systems to only support 32 bit integers may be the easy solution, but bigint is an essential element of most database type sets these days, so should be supported transparently. If a primary key is provided as part of a database result set, then do we really want the situation where some installs fall over with an overflow of that key on 32 bit systems? Having to use a secondary level function exclusively simply because the core processing gets it wrong is another mistake? Certainly it's not going to be easy to handle, and may not even be practical? But even the discussion on 'type hinting' seems to ignore the range problem where a 64bit value may be required but the installation on4y supports 32bit integers. Currently the value simply works with the string version ...
-- Lester Caine - G8HFL ----------------------------- Contact - http://lsces.co.uk/wiki/?page=contact L.S.Caine Electronic Services - http://lsces.co.uk EnquirySolve - http://enquirysolve.com/ Model Engineers Digital Workshop - http://medw.co.uk Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

Andrew Faulds

12 years ago
On 15 Jul 2014, at 08:06, Lester Caine <lester@lsces.co.uk> wrote:
> Taking this in isolation is wrong ... > It is essentially linked up with all of the discussion on '64bit' > processing. What seems to be ignored so far is the simple 'bigint' > value. Limiting 32 bit systems to only support 32 bit integers may be > the easy solution, but bigint is an essential element of most database > type sets these days, so should be supported transparently. If a primary > key is provided as part of a database result set, then do we really want > the situation where some installs fall over with an overflow of that key > on 32 bit systems? Having to use a secondary level function exclusively > simply because the core processing gets it wrong is another mistake? > > Certainly it's not going to be easy to handle, and may not even be > practical? But even the discussion on 'type hinting' seems to ignore the > range problem where a 64bit value may be required but the installation > on4y supports 32bit integers. Currently the value simply works with the > string version …
Yeah, hence why I’m also proposing the bigint RFC, which intdiv() would work nicely with.
-- Andrea Faulds http://ajf.me/

Andrew Faulds

12 years ago
On 15 Jul 2014, at 06:17, Stas Malyshev <smalyshev@sugarcrm.com> wrote:
> Why not? bcmath is in core since forever and has no external > requirements, gmp builds practically everywhere too. AFAIR all distros > have it.
Partly practicality, partly principle. A barebones installation of PHP may not include gmp or bcmath. If my bigint RFC got in, it would have to include the former, but that is a possible future and not the present reality. I should point out that while, yes, bcmath could be used here, it is not efficient to do it by string manipulation (this is a type *natively supported* by literally every semi-modern processor and an operation built into C!). Also, gmp does the wrong thing, as will give you a gmp number result, whereas what I want is an integer. To use gmp is just as hackish as doing a floating-point division and casting, as the values we pass in would be converted to big integers, divided, then the resulting big integer would need to be manually converted back to a long. It would make far more sense to simply support this basic, widely-supported and somewhat common operation than to encourage programmers to use poor workarounds which do not even work when a basic PHP installation is used.
-- Andrea Faulds http://ajf.me/

Yasuo Ohgaki

12 years ago
Hi Andrea, On Tue, Jul 15, 2014 at 9:14 AM, Andrea Faulds <ajf@ajf.me> wrote:
> PHP currently lacks a way to do integer division. You can floor or int > cast a floating-point division, but beyond 53-bits that produces the wrong > result: > > $ sapi/cli/php -r 'var_dump((int)(PHP_INT_MAX / 3));' > int(3074457345618258432) > > Furthermore, using a floating-point division isn’t really a proper way to > do it; it’s a workaround for a lack of language support for a quite basic > operation. This RFC proposes a function for integer division, intdiv(). It > would work properly with 64-bit values: > > $ sapi/cli/php -r 'var_dump(intdiv(PHP_INT_MAX, 3));' > int(3074457345618258602) >
We have GMP object from 5.6 and we can do [yohgaki@dev php-5.6]$ ./php-bin -r '$i = gmp_init('21342'); $a = $i / 3; var_dump($a);' object(GMP)#2 (1) { ["num"]=> string(4) "7114" } [yohgaki@dev php-5.6]$ ./php-bin -r '$i = gmp_init('21342'); $a = $i * 99999999; var_dump($a);' object(GMP)#2 (1) { ["num"]=> string(13) "2134199978658" } IMHO, GMP is the choice when precise computation is needed as it could be any number. Native integer type is much faster for sure. Question is do we really need it? Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Yasuo Ohgaki

12 years ago
Hi Andrea, On Tue, Jul 15, 2014 at 11:10 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote:
> On Tue, Jul 15, 2014 at 9:14 AM, Andrea Faulds <ajf@ajf.me> wrote: > >> PHP currently lacks a way to do integer division. You can floor or int >> cast a floating-point division, but beyond 53-bits that produces the wrong >> result: >> >> $ sapi/cli/php -r 'var_dump((int)(PHP_INT_MAX / 3));' >> int(3074457345618258432) >> >> Furthermore, using a floating-point division isn’t really a proper way to >> do it; it’s a workaround for a lack of language support for a quite basic >> operation. This RFC proposes a function for integer division, intdiv(). It >> would work properly with 64-bit values: >> >> $ sapi/cli/php -r 'var_dump(intdiv(PHP_INT_MAX, 3));' >> int(3074457345618258602) >> > > We have GMP object from 5.6 and we can do > > [yohgaki@dev php-5.6]$ ./php-bin -r '$i = gmp_init('21342'); $a = $i / 3; > var_dump($a);' > object(GMP)#2 (1) { > ["num"]=> > string(4) "7114" > } > [yohgaki@dev php-5.6]$ ./php-bin -r '$i = gmp_init('21342'); $a = $i * > 99999999; var_dump($a);' > object(GMP)#2 (1) { > ["num"]=> > string(13) "2134199978658" > } > > IMHO, GMP is the choice when precise computation is needed as it could be > any number. > Native integer type is much faster for sure. Question is do we really need > it? >
If we are going to have integer arithmetics, it may be better to have full set of operators/functions https://bugs.php.net/bug.php?id=30701 Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Andrew Faulds

12 years ago
On 15 Jul 2014, at 23:12, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote:
> If we are going to have integer arithmetics, it may be better to have full set of operators/functions > > https://bugs.php.net/bug.php?id=30701
I’d rather not go to that length, but if someone wants to do that, they may. Bigints might help here… although they might also cause more problems in places.
-- Andrea Faulds http://ajf.me/

Bishop Bettini

12 years ago
Hi Andrea, I need some education. Can you elaborate on the specific situations where integer division would be used without other functions from bcmath or gmp? I see in the RFC you mention seconds to hh:mm and index to rows/cols, but can you give some actual "before" and "after" samples? Like this is how it would be done today without intdiv, and here's how it would be done after? Regards, bishop On Jul 14, 2014 8:15 PM, "Andrea Faulds" <ajf@ajf.me> wrote:

Andrew Faulds

12 years ago
On 15 Jul 2014, at 03:31, Bishop Bettini <bishop@php.net> wrote:
> I need some education. Can you elaborate on the specific situations where integer division would be used without other functions from bcmath or gmp? > > I see in the RFC you mention seconds to hh:mm and index to rows/cols, but can you give some actual "before" and "after" samples? Like this is how it would be done today without intdiv, and here's how it would be done after?
Sure. Say I have a number of seconds which I wish to split into years, days, hours, minutes and seconds, for example: $s = 1000000; $seconds = $s % 60; $minutes = intdiv($s, 60) % 60; $hours = intdiv($s, 3600) % 24; $days = intdiv($s, 3600 * 24) % 365; $years = intdiv($s, 3600 * 24 * 365); Currently, you’d have to cheat and use floating-point division: $x = 1000000; $seconds = $s % 60; $minutes = (int)($s / 60) % 60; $hours = (int)($s / 3600) % 24; $days = (int)($s / (3600 * 24)) % 365; $years = (int)($s / (3600 * 24 * 365)); The second one is a bit of a hack, really, but it would probably work most of the time since realistically nobody is using >53-bit time values at the moment (though people are using >32-bit values, so that 64-bit RFC can’t come soon enough given Y2K38). However, intdiv() is perhaps not the best way to implement it or the best syntax.
-- Andrea Faulds http://ajf.me/

Bishop Bettini

12 years ago
Hi Andrea, TL;DR -- I agree with the principal but want implemented as the infix operator %% with a test for PHP_INT_MIN %% -1 === false (and a E_WARNING). As a user, I could implement intdiv and get the same functionality as proposed: function intdiv($n, $d) { return (int)($n / $d); } Heck, I could even simplify further: function intdivmod($n, $d, $m = 1) { return (int)($n / $d) % $m; } Though an internal implementation would be faster and would bypass the float truncation issue (which IMO is a separate issue and neither a pro nor con for this RFC), I feel like we need to confer additional benefit if we implement this in core. Specifically, I'd want this implemented infix. Let's call it // for now. I'd like to be able to: $x = 247 // 5; $x //= 5; The functional notation doesn't afford assign equals. It collides with user functions. It complicates expressions. (I also don't like pow() functionally and wish PHP had an operator like ** for powers.) So, why not implement this as an actual operator? As far as an operator, that's trickier. // and \ would be most like existing languages, but those are problematic as already stated. We could overload /, relying on the left and right operands to be int to induce integer division... but I'm pretty sure that would be more hassle than it's worth. So the best I can think of is %%. That seems ok to me, since there is some family resemblance between modulus and integer division. Finally, I think a test on the other side of the spectrum is needed: PHP_INT_MIN %% -1. Mathematically that should be PHP_INT_MAX+1, I believe, so a warning and false seems appropriate. Regards, bishop On Jul 15, 2014 8:11 AM, "Andrea Faulds" <ajf@ajf.me> wrote:

Andrew Faulds

12 years ago
On 16 Jul 2014, at 02:51, Bishop Bettini <bishop@php.net> wrote:
> Hi Andrea, > > TL;DR -- I agree with the principal but want implemented as the infix > operator %% with a test for PHP_INT_MIN %% -1 === false (and a E_WARNING).
%% is perhaps the only good non-keyword syntax choice. I like that.
> As a user, I could implement intdiv and get the same functionality as > proposed: > function intdiv($n, $d) { return (int)($n / $d); }
You could, yes, but it wouldn’t return the correct result beyond 53-bit integers, and I’m not sure it would handle $x/-1 particularly well.
> > Heck, I could even simplify further: > function intdivmod($n, $d, $m = 1) { > return (int)($n / $d) % $m; > } > > Though an internal implementation would be faster and would bypass the > float truncation issue (which IMO is a separate issue and neither a pro nor > con for this RFC), I feel like we need to confer additional benefit if we > implement this in core. > > Specifically, I'd want this implemented infix. Let's call it // for now. > I'd like to be able to: > > $x = 247 // 5; > $x //= 5; > > The functional notation doesn't afford assign equals. It collides with > user functions. It complicates expressions. (I also don't like pow() > functionally and wish PHP had an operator like ** for powers.) So, why not > implement this as an actual operator?
PHP *does* have an operator “like **” for powers… the ** operator. Did you somehow miss that RFC passing? :)
> > As far as an operator, that's trickier. // and \ would be most like > existing languages, but those are problematic as already stated. We could > overload /, relying on the left and right operands to be int to induce > integer division... but I'm pretty sure that would be more hassle than it's > worth. So the best I can think of is %%. That seems ok to me, since there > is some family resemblance between modulus and integer division.
Right. This is just returning the other part of an integer division, the actual result itself, not the remainder.
> Finally, I think a test on the other side of the spectrum is needed: > PHP_INT_MIN %% -1. Mathematically that should be PHP_INT_MAX+1, I believe, > so a warning and false seems appropriate.
The patch currently returns zero because I don’t want to yield a float like / does, but E_WARNING and FALSE sounds good, we do that for integer division anyway. Do others on internals think that %% is a good syntax choice? Does anyone have an objection to it? It wouldn’t conflict with anything, it uses punctuation, and it makes sense.
-- Andrea Faulds http://ajf.me/

Andrew Faulds

12 years ago
On 16 Jul 2014, at 02:51, Bishop Bettini <bishop@php.net> wrote:
> TL;DR -- I agree with the principal but want implemented as the infix > operator %% with a test for PHP_INT_MIN %% -1 === false (and a E_WARNING).
The RFC has been updated to v0.2. It now proposes a %% operator for integer division (with corresponding %%= assignment operator). However, it returns 0 for the PHP_INT_MIN overflow case like %, rather than FALSE and an E_WARNING. The original intdiv() proposal is kept as a fallback; two votes will be held simultaneously, one 2/3 vote for the %% operator and a 50%+1 for the intdiv() function. If the first fails, then if the second did not, the intdiv() function is implemented instead. This way we’ll still at least have a way to do integer division in PHP, if not a full operator. Nikita Popov doesn’t seem to be a fan of the %% syntax, so it may be subject to change, though I think it’s the best I’ve heard so far. ;)
-- Andrea Faulds http://ajf.me/

Sara Golemon

12 years ago
On Wed, Jul 16, 2014 at 8:15 AM, Andrea Faulds <ajf@ajf.me> wrote:
> Nikita Popov doesn’t seem to be a fan of the %% syntax, so it may be subject to change, though I think it’s the best I’ve heard so far. ;) >
Nor am I. Here's a thought though: How about just making / return int when there's no remainder. Looking at this code, you might think it's inefficent: double dres = a / b; long lres = a / b; if (a % b) { return dres; } else { return lres; } But in fact at -O1, gcc will optimize this (probably clang and others as well) to a single idivq instruction and only do the cvtsi2sdq in the dres case. My point being, we can just make division with an integral result return a result of integer division without altering the syntax or adding a perf hit. -Sara

Tjerk Meesters

12 years ago
Hi Sara, On Thu, Jul 17, 2014 at 8:25 AM, Sara Golemon <pollita@php.net> wrote:
> On Wed, Jul 16, 2014 at 8:15 AM, Andrea Faulds <ajf@ajf.me> wrote: > > Nikita Popov doesn’t seem to be a fan of the %% syntax, so it may be > subject to change, though I think it’s the best I’ve heard so far. ;) > > > Nor am I. Here's a thought though: How about just making / return int > when there's no remainder. > > Looking at this code, you might think it's inefficent: > > double dres = a / b; > long lres = a / b; > if (a % b) { > return dres; > } else { > return lres; > } > > But in fact at -O1, gcc will optimize this (probably clang and others > as well) to a single idivq instruction and only do the cvtsi2sdq in > the dres case. >
Just out of curiosity, does the compiler optimise it into something like this? if (a % b) { return a / b; } else { return (double)a / b; } Or, would writing it like that skip the optimisation of being able to fetch the division result from %rax?
> My point being, we can just make division with an integral result > return a result of integer division without altering the syntax or > adding a perf hit. > > -Sara > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
-- -- Tjerk

Sara Golemon

12 years ago
On Wed, Jul 16, 2014 at 6:51 PM, Tjerk Meesters <tjerk.meesters@gmail.com> wrote:
> Just out of curiosity, does the compiler optimise it into something like > this? > > if (a % b) { > return a / b; > } else { > return (double)a / b; > } >
Ya know what? I feel dumb. FP division is a whole separate instruction. I forgot that (int/int) is always int, even if you're storing in a double. Derp. So yeah, In that code you pasted, you get a single idivq in the int args with no remainder case, but you do have to do a divsd in the remainder exists case. So not as perf neutral as I was thinking. Beneficial in the int case since idivq is less costly than divsd, but the common case may well be ((a%b)!=0), so it's probably harmful more often than not. All that said, *I* think the tradeoff of an extra idivq in the (probably more common) remainder case is worth it in the interest of keeping PHP's syntax simple. If we're really set on adding a new operator, I'd vote for something which provides dividend *and* remainder in some way. (Useful for time arithmetic, for example) -Sara

Nikita Popov

12 years ago
On Thu, Jul 17, 2014 at 2:25 AM, Sara Golemon <pollita@php.net> wrote:
> On Wed, Jul 16, 2014 at 8:15 AM, Andrea Faulds <ajf@ajf.me> wrote: > > Nikita Popov doesn’t seem to be a fan of the %% syntax, so it may be > subject to change, though I think it’s the best I’ve heard so far. ;) > > > Nor am I. Here's a thought though: How about just making / return int > when there's no remainder. > > Looking at this code, you might think it's inefficent: > > double dres = a / b; > long lres = a / b; > if (a % b) { > return dres; > } else { > return lres; > } > > But in fact at -O1, gcc will optimize this (probably clang and others > as well) to a single idivq instruction and only do the cvtsi2sdq in > the dres case. > > My point being, we can just make division with an integral result > return a result of integer division without altering the syntax or > adding a perf hit. >
This is already what is currently happening, see http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_operators.c#1067. Andreas proposal is only useful in the case that the numbers don't divide exactly and you need round-down/truncation behavior and your numbers are in a range where the indirection through double arithmetic results in precision loss. Nikita

Andrew Faulds

12 years ago
On 17 Jul 2014, at 10:24, Nikita Popov <nikita.ppv@gmail.com> wrote:
> This is already what is currently happening, see > http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_operators.c#1067. > > Andreas proposal is only useful in the case that the numbers don't divide > exactly and you need round-down/truncation behavior and your numbers are in > a range where the indirection through double arithmetic results in > precision loss.
It’s still useful regardless as it saves you implementing it in terms of floats. I mean, you can implement a right shift (rarely used outside bit masks) in terms of multiplication and exponentiation, but that doesn’t mean you shouldn’t have a right shift.
-- Andrea Faulds http://ajf.me/

Kris Craig

12 years ago
On Thu, Jul 17, 2014 at 6:31 AM, Andrea Faulds <ajf@ajf.me> wrote:
> > On 17 Jul 2014, at 10:24, Nikita Popov <nikita.ppv@gmail.com> wrote: > > > This is already what is currently happening, see > > http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_operators.c#1067. > > > > Andreas proposal is only useful in the case that the numbers don't divide > > exactly and you need round-down/truncation behavior and your numbers are > in > > a range where the indirection through double arithmetic results in > > precision loss. > > It’s still useful regardless as it saves you implementing it in terms of > floats. > > I mean, you can implement a right shift (rarely used outside bit masks) in > terms of multiplication and exponentiation, but that doesn’t mean you > shouldn’t have a right shift. > > -- > Andrea Faulds > http://ajf.me/ > > > > > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
There seems to be a pretty even split on this. Personally, I'm a +1 for it. PHP has tons of obscure, rarely used functions. Even if the gain is relatively minor, there's really no cost that I can think of. So from a cost-benefit standpoint, even a minor improvement is still desirable when there's no practical downside to it. Given the number of options that are coming up, I'd suggest you break the RFC down into two votes: A simple yes/no vote followed by an "if yes, how should it be implemented?" vote with the various options (the operators, functions, etc). If the RFC passes, then whichever option got a plurality of the votes would be the implemented option. So yeah, I'd say bring it to a vote and that'll settle it one way or another. --Kris

Tjerk Meesters

12 years ago
On Fri, Jul 18, 2014 at 10:47 AM, Kris Craig <kris.craig@gmail.com> wrote:
> On Thu, Jul 17, 2014 at 6:31 AM, Andrea Faulds <ajf@ajf.me> wrote: > > > > > On 17 Jul 2014, at 10:24, Nikita Popov <nikita.ppv@gmail.com> wrote: > > > > > This is already what is currently happening, see > > > http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_operators.c#1067. > > > > > > Andreas proposal is only useful in the case that the numbers don't > divide > > > exactly and you need round-down/truncation behavior and your numbers > are > > in > > > a range where the indirection through double arithmetic results in > > > precision loss. > > > > It’s still useful regardless as it saves you implementing it in terms of > > floats. > > > > I mean, you can implement a right shift (rarely used outside bit masks) > in > > terms of multiplication and exponentiation, but that doesn’t mean you > > shouldn’t have a right shift. > > > > -- > > Andrea Faulds > > http://ajf.me/ > > > > > > > > > > > > -- > > PHP Internals - PHP Runtime Development Mailing List > > To unsubscribe, visit: http://www.php.net/unsub.php > > > > > There seems to be a pretty even split on this. Personally, I'm a +1 for > it. PHP has tons of obscure, rarely used functions. Even if the gain is > relatively minor, there's really no cost that I can think of. So from a > cost-benefit standpoint, even a minor improvement is still desirable when > there's no practical downside to it. > > Given the number of options that are coming up, I'd suggest you break the > RFC down into two votes: A simple yes/no vote followed by an "if yes, how > should it be implemented?" vote with the various options (the operators, > functions, etc). If the RFC passes, then whichever option got a plurality > of the votes would be the implemented option. >
This makes it more complicated because a language change requires 2/3 majority while a new function requires 50% + 1. To make things simpler - and I believe it had been proposed before - the main vote should include the implementation as a function and the secondary vote should be for the operator.
> > So yeah, I'd say bring it to a vote and that'll settle it one way or > another. > > --Kris >
-- -- Tjerk

Zeev Suraski

12 years ago
> -----Original Message----- > From: Andrea Faulds [mailto:ajf@ajf.me] > Sent: Wednesday, July 16, 2014 6:15 PM > To: bishop@php.net > Cc: PHP internals > Subject: Re: [PHP-DEV] [RFC] intdiv() > > The RFC has been updated to v0.2. It now proposes a %% operator for
integer
> division (with corresponding %%= assignment operator). However, it
returns 0
> for the PHP_INT_MIN overflow case like %, rather than FALSE and an > E_WARNING.
Guys, From debating whether it's worth it to add a new function for an not-so-commonly-used-operation-to-say-the-least, we're now seriously considering adding a new language level operator? Really? Zeev

Andrew Faulds

12 years ago
On 17 Jul 2014, at 07:29, Zeev Suraski <zeev@zend.com> wrote:
> From debating whether it's worth it to add a new function for an > not-so-commonly-used-operation-to-say-the-least, we're now seriously > considering adding a new language level operator? Really?
Is it *really* not that common? I can think of several use-cases off the top of my head: * Time (actually pretty common in web apps, though we have a DateTime class) * Splitting into rows and columns * Pagination * Currency (you can’t, for example, represent the full number of BTC in circulation in BTC's base unit without using an integer of beyond 53-bits, and it’s common practise to use *fixed-point* arithmetic here) * Nearest-neighbour scaling * Most likely other ones (these are just what I thought of immediately) Also, while ** is great for some applications, it’s not going to be used much by others. Is the same not true of an integer division operator? On 17 Jul 2014, at 07:31, Zeev Suraski <zeev@zend.com> wrote:
> I can't believe we're seriously considering adding an operator for something > so uncommon. > > I'm actually in favor of adding APIs, but absolutely not an obscure > operator. We're not Perl.
Nor are we Python, but it is worth looking at just how many other languages support this considering it’s actually very useful in some situations. I can think of C, C++, C#, Java, Objective-C, Visual Basic, Pascal, Python and Ruby to name a few popular ones. If you say that some of these implement it just because C does, I’m not sure that’s fair, as there are plenty of bad ideas in C which these don’t implement.
-- Andrea Faulds http://ajf.me/

Pierre Joye

12 years ago
Hi Andrea, On Thu, Jul 17, 2014 at 8:44 AM, Andrea Faulds <ajf@ajf.me> wrote:
> > On 17 Jul 2014, at 07:29, Zeev Suraski <zeev@zend.com> wrote: > >> From debating whether it's worth it to add a new function for an >> not-so-commonly-used-operation-to-say-the-least, we're now seriously >> considering adding a new language level operator? Really? > > Is it *really* not that common? I can think of several use-cases off the top of my head: > > * Time (actually pretty common in web apps, though we have a DateTime class) > * Splitting into rows and columns > * Pagination > * Currency (you can’t, for example, represent the full number of BTC in circulation in BTC's base unit without using an integer of beyond 53-bits, and it’s common practise to use *fixed-point* arithmetic here) > * Nearest-neighbour scaling > * Most likely other ones (these are just what I thought of immediately) > > Also, while ** is great for some applications, it’s not going to be used much by others. Is the same not true of an integer division operator?
The rare cases where I had to do that, I relied on bcmath or gmp. Yes, I needed some extra ops to actually achieve what this RFC proposes but it is good enough. The new ops overloading for extension simplifies that a lot as well. I am sorry but I'd to say -1 on this addition, not worse a new operator or function for this. Cheers,
-- Pierre @pierrejoye | http://www.libgd.org

Andrew Faulds

12 years ago
On 17 Jul 2014, at 07:56, Pierre Joye <pierre.php@gmail.com> wrote:
> The rare cases where I had to do that, I relied on bcmath or gmp. Yes, > I needed some extra ops to actually achieve what this RFC proposes but > it is good enough. The new ops overloading for extension simplifies > that a lot as well. > > I am sorry but I'd to say -1 on this addition, not worse a new > operator or function for this.
How on earth is adding a nearly-universal function everywhere else to PHP’s math library so controversial, let alone as an operator? Yes, you *can* do it with bcmath or gmp, but one should question why you *should*, given that it’s a horrible workaround.
-- Andrea Faulds http://ajf.me/

Zeev Suraski

12 years ago
> -----Original Message----- > From: Andrea Faulds [mailto:ajf@ajf.me] > Sent: Thursday, July 17, 2014 9:44 AM > To: Zeev Suraski > Cc: bishop@php.net; PHP internals > Subject: Re: [PHP-DEV] [RFC] intdiv() > > > On 17 Jul 2014, at 07:29, Zeev Suraski <zeev@zend.com> wrote: > > > From debating whether it's worth it to add a new function for an > > not-so-commonly-used-operation-to-say-the-least, we're now seriously > > considering adding a new language level operator? Really? > > Is it *really* not that common? I can think of several use-cases off the
top of
> my head: > > * Time (actually pretty common in web apps, though we have a DateTime > class) > * Splitting into rows and columns > * Pagination > * Currency (you can't, for example, represent the full number of BTC in > circulation in BTC's base unit without using an integer of beyond
53-bits, and
> it's common practise to use *fixed-point* arithmetic here) > * Nearest-neighbour scaling > * Most likely other ones (these are just what I thought of immediately)
I think it is, given I believe it's the first time people are asking for this after PHP's been out for almost two decades... As the RFC itself suggests, you can use the current division for most use cases, including the ones mentioned above - they'd work in the vast majority of cases. I think the RFC should mention that it's already possible to do it using bcmath or gmp; That said, I tend to agree that we should have something like that in ext/standard, so I'm actually in favor of doing it - just not as an operator.
> Also, while ** is great for some applications, it's not going to be used
much by
> others. Is the same not true of an integer division operator?
To be honest, that operator was simply copied verbatim from Perl, back in the day when Perl ruled the Web world and minimizing the learning curve for Perl developers was an important goal. Not sure if we'd add it to the language had we not 'plagiarized' it from Perl... Zeev

Andrew Faulds

12 years ago
On 17 Jul 2014, at 08:02, Zeev Suraski <zeev@zend.com> wrote:
> I think it is, given I believe it's the first time people are asking for > this after PHP's been out for almost two decades... > As the RFC itself suggests, you can use the current division for most use > cases, including the ones mentioned above - they'd work in the vast > majority of cases.
Yes, but as previously mentioned, beyond 2^52 it breaks down. What’s more worrying is the code out there written by people obviously unaware of this, but I shouldn’t use MtGox’s incompetence as a reason to fix PHP ;)
> I think the RFC should mention that it's already possible to do it using > bcmath or gmp;
It’s not possible to do with bcmath or gmp within the brief of “find the quotient of the division of two longs without requiring an extension”. Neither bcmath nor gmp is core PHP, and neither operate on longs, though you can be silly and convert a long to a string, in bcmath’s case, or a gmp object, in gmp’s case, then do the operation, then convert back, checking for the two failure cases, of course.
> That said, I tend to agree that we should have something > like that in ext/standard, so I'm actually in favor of doing it - just not > as an operator.
Well, that’s better than nothing I suppose, but I’d still rather use something infix.
> To be honest, that operator was simply copied verbatim from Perl, back in > the day when Perl ruled the Web world and minimizing the learning curve > for Perl developers was an important goal. Not sure if we'd add it to the > language had we not 'plagiarized' it from Perl…
Huh? ** was added by an RFC this year. Actually, since 5.6 isn’t out yet, it’s technically not part of PHP yet...
-- Andrea Faulds http://ajf.me/

Zeev Suraski

12 years ago
> -----Original Message----- > From: Andrea Faulds [mailto:ajf@ajf.me] > Sent: Thursday, July 17, 2014 10:09 AM > To: Zeev Suraski > Cc: bishop@php.net; PHP internals > Subject: Re: [PHP-DEV] [RFC] intdiv() > > > On 17 Jul 2014, at 08:02, Zeev Suraski <zeev@zend.com> wrote: > > > I think it is, given I believe it's the first time people are asking > > for this after PHP's been out for almost two decades... > > As the RFC itself suggests, you can use the current division for most > > use cases, including the ones mentioned above - they'd work in the > > vast majority of cases. > > Yes, but as previously mentioned, beyond 2^52 it breaks down. What's
more
> worrying is the code out there written by people obviously unaware of
this,
> but I shouldn't use MtGox's incompetence as a reason to fix PHP ;) > > > I think the RFC should mention that it's already possible to do it > > using bcmath or gmp; > > It's not possible to do with bcmath or gmp within the brief of "find the > quotient of the division of two longs without requiring an extension".
Neither
> bcmath nor gmp is core PHP, and neither operate on longs, though you can
be
> silly and convert a long to a string, in bcmath's case, or a gmp object,
in gmp's
> case, then do the operation, then convert back, checking for the two
failure
> cases, of course.
It's still possible to do. When people vote on a new feature the full context should be clear. Again, I'm supporting your RFC (in its original form at least) - but we should provide as much information as possible in the RFC to give voters the full context.
> > That said, I tend to agree that we should have something like that in > > ext/standard, so I'm actually in favor of doing it - just not as an > > operator. > > Well, that's better than nothing I suppose, but I'd still rather use
something
> infix.
PHP's not Perl. Let's keep it that way please...
> > To be honest, that operator was simply copied verbatim from Perl, back > > in the day when Perl ruled the Web world and minimizing the learning > > curve for Perl developers was an important goal. Not sure if we'd add > > it to the language had we not 'plagiarized' it from Perl. > > Huh? ** was added by an RFC this year. Actually, since 5.6 isn't out
yet, it's
> technically not part of PHP yet...
OK, this RFC passed well under my radar. I thought we had it forever, and indeed I never found a reason to use it :) I'd probably vote against it if I was aware of it, but given it's common in other languages, I wouldn't have strongly opposed it. I don't think it makes sense to add a specialized integer division operator when we do have a different division operator, and I don't think other dynamic languages have such an operator - so unlike **, there's no established precedent... Zeev

Lester Caine

12 years ago
On 17/07/14 08:02, Zeev Suraski wrote:
> I think it is, given I believe it's the first time people are asking for > this after PHP's been out for almost two decades... > As the RFC itself suggests, you can use the current division for most use > cases, including the ones mentioned above - they'd work in the vast > majority of cases.
What has happened in the intervening 20 years is that we have moved from having 16 bit computer systems on the desk to 64bit computers on our wrists? Coming up with some new operator is a pointless distraction. The ones we have are enough, they just need to be brought into the 21st century consistently, yet still work on the historic machines some people stile prefer ... just as PHP needs to handle unicode transparently it also needs to handle 64bit integers ...
-- Lester Caine - G8HFL ----------------------------- Contact - http://lsces.co.uk/wiki/?page=contact L.S.Caine Electronic Services - http://lsces.co.uk EnquirySolve - http://enquirysolve.com/ Model Engineers Digital Workshop - http://medw.co.uk Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

Stas Malyshev

12 years ago
Hi!
> * Time (actually pretty common in web apps, though we have a DateTime > class)
Admittedly, we're getting closer to the dreaded year 2038, but what does it actually mean to divide current Unix timestamp by 3 and why one would ever want to do this? We also have classes for real datetime calculations.
> * Splitting into rows and columns > * Pagination
Here you are onto something, but how often you paginate data sets of MAXINT size and need exact number of pages?
> * Currency (you can’t, for example, represent the full number of BTC > in circulation in BTC's base unit without using an integer of beyond > 53-bits, and it’s common practise to use *fixed-point* arithmetic > here)
If you're using ints for currency, you're probably doing it wrong. If you're dividing currency using integer division, I don't even know what you are trying to do, except reenacting Office Space :)
> * Nearest-neighbour scaling
You mean image processing? If 53 bit precision is not enough there, I'm not even sure PHP should be doing that. IMHO this is not enough for a new operator... Especially if this means we have to tolerate something like %/.
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/

Andrew Faulds

12 years ago
On 17 Jul 2014, at 08:17, Stas Malyshev <smalyshev@sugarcrm.com> wrote:
> Hi! > >> * Time (actually pretty common in web apps, though we have a DateTime >> class) > > Admittedly, we're getting closer to the dreaded year 2038, but what does > it actually mean to divide current Unix timestamp by 3 and why one would > ever want to do this? We also have classes for real datetime calculations.
To divide by three is probably a bad example, but it’s fair to point out that anything with UNIX timestamps would work fine with just floats as we don’t need 53 bits yet.
> Here you are onto something, but how often you paginate data sets of > MAXINT size and need exact number of pages?
Rarely, I suspect, but it would still be nice to have a proper way of doing the division
> If you're using ints for currency, you're probably doing it wrong. If > you're dividing currency using integer division, I don't even know what > you are trying to do, except reenacting Office Space :)
A lot of people use ints as a poor man’s fixnum, and sometimes that’s actually the right way to implement them. IIRC, Bitcoin is implemented using 64-bit integers internally.
> You mean image processing? If 53 bit precision is not enough there, I'm > not even sure PHP should be doing that.
True, but again, you should still ask why PHP doesn’t support integer division in the first place.
> IMHO this is not enough for a new operator... Especially if this means > we have to tolerate something like %/.
%/ and %% are hardly the nicest operators, no. Myself I like %% as % being one part and %% being the other part of an integer division makes sense to me, but I can see why others might not like it.
-- Andrea Faulds http://ajf.me/