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/
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/
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/
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/
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/--
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
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/
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 anintdiv()
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.
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
-----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()
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
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
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/
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/
Hi Andrea,
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
Hi Andrea,
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
If we are going to have integer arithmetics, it may be better to have full set of operators/functions
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/
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
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 (à lapow()
), 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/
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/
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
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/
Hi Andrea,
TL;DR -- I agree with the principal but want implemented as the infix
operator %% with a test forPHP_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 likepow()
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/
TL;DR -- I agree with the principal but want implemented as the infix
operator %% with a test forPHP_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/
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
Hi Sara,
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
--
--
Tjerk
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 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
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/
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/--
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
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/--
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
On Thu, Jul 17, 2014 at 8:39 PM, Tjerk Meesters tjerk.meesters@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/--
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
The problem is that, since that suggestion, other variations have been
proposed with no clear favorite. How should we decide which proposed
operator, for example? There have been several mentioned.
--Kris
On Thu, Jul 17, 2014 at 8:39 PM, Tjerk Meesters tjerk.meesters@gmail.com
wrote:On Fri, Jul 18, 2014 at 10:47 AM, Kris Craig kris.craig@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/--
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
The problem is that, since that suggestion, other variations have been
proposed with no clear favorite. How should we decide which proposed
operator, for example? There have been several mentioned.
If the author can't settle on a particular operator, then a third vote
would be necessary for those who vote to have an operator in the first
place; perhaps a simple majority required for that.
--Kris
--
Tjerk
On Thu, Jul 17, 2014 at 9:18 PM, Tjerk Meesters tjerk.meesters@gmail.com
wrote:
On Thu, Jul 17, 2014 at 8:39 PM, Tjerk Meesters <tjerk.meesters@gmail.com
wrote:
On Fri, Jul 18, 2014 at 10:47 AM, Kris Craig kris.craig@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/--
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
The problem is that, since that suggestion, other variations have been
proposed with no clear favorite. How should we decide which proposed
operator, for example? There have been several mentioned.If the author can't settle on a particular operator, then a third vote
would be necessary for those who vote to have an operator in the first
place; perhaps a simple majority required for that.--Kris
--
Tjerk
Hmm ok that sounds reasonable.
--Kris
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.
That’s the current proposal in the RFC. A 2/3 operator vote simultaneous with a fallback 50%+1 function vote.
--
Andrea Faulds
http://ajf.me/
-----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 thePHP_INT_MIN
overflow case like %, rather thanFALSE
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
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?
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/
Hi Andrea,
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
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/
-----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()
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
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/
-----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()
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
PHP's not Perl. Let's keep it that way please…
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…
True, but PHP clearly drew inspiration from Perl, and C, which also has integer division.
Many of these languages don’t have an integer division operator simply because they don’t need one. In most C-like languages and plenty of non C-like, an integer divided by an integer is always an integer, and you only get a float result if one or more operands are a float. However, in languages like PHP, Python, Visual Basic and Pascal, the division operator is unusually (though I’d say more intuitively) defined as sometimes giving a float for integer operands. In the case of PHP and Python, this is only when the the second operand isn’t a factor, while in the case of VB and Pascal, / always results in a float. It is in these languages that we find the much rarer integer division operator (Python has //, Visual Basic has , Pascal has div) because you can’t do it the “normal” way. In this respect, it’s rather unusual that PHP lacks an integer division operator, or even some built-in way to do integer division at all, given that all its peers do support it.
There are also languages which don’t have integers, like JavaScript. In JS there’s no need for such an operator as, since it doesn’t have integers anyway, Math.floor(x / y) isn’t going to lose any accuracy.
Makes me wonder why we don’t have one after all these years. I assume either the division operator hasn’t always done what id does now (I’m not a historian, so I couldn’t tell you that), or that people have tended to just go for floor(x / y). After all, that works perfectly on 32-bit platforms. ;)
Andrea Faulds
http://ajf.me/
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
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/
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/