Doc #53934 [ReO->Csd]: The negative PHP_INT_MAX is incorrectly converted to float
| From: | cmb@php.net | Date: | Tue, 29 May 2018 13:41:36 +0000 |
| Subject: | Doc #53934 [ReO->Csd]: The negative PHP_INT_MAX is incorrectly converted to float | ||
| References: | 1 | Groups: | php.doc.bugs |
| Request: | Send a blank email to doc-bugs+get-15726@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=53934&edit=1
ID: 53934
Updated by: cmb@php.net
Reported by: eriksen dot costa at infranology dot com dot br
Summary: The negative PHP_INT_MAX is incorrectly converted to
float
-Status: Re-Opened
+Status: Closed
Type: Documentation Problem
Package: Scripting Engine problem
Operating System: Linux
PHP Version: 5.3.5
Assigned To: cmb
Block user comment: N
Private report: N
New Comment:
This bug has been fixed in the documentation's XML sources. Since the
online and downloadable versions of the documentation need some time
to get updated, we would like to ask you to be a bit patient.
Thank you for the report, and for helping us make our documentation better.
Previous Comments:
------------------------------------------------------------------------
[2018-05-29 13:41:04] cmb@php.net
Automatic comment from SVN on behalf of cmb
Revision: http://svn.php.net/viewvc/?view=revision&revision=345073
Log: Fix #53934: The negative PHP_INT_MAX is incorrectly converted to float
Actually, PHP does not support integer literals with explicit signs;
instead these are regarded as identity and negation operators, respectively.
------------------------------------------------------------------------
[2018-05-29 13:07:30] cmb@php.net
Re-opening and changing to documentation problem, since[1]
| Integers can be specified in decimal (base 10), hexadecimal
| (base 16), octal (base 8) or binary (base 2) notation, optionally
| preceded by a sign (- or +).
is misleading at best.
[1] <http://php.net/manual/en/language.types.integer.php#language.types.integer.syntax>
------------------------------------------------------------------------
[2018-05-29 12:53:48] nikic@php.net
@spam2 at rhsoft dot net: 9223372036854775808 is not INT_MAX, you were probably thinking about
9223372036854775807? Under signed compliment, INT_MAX and INT_MIN are off by one.
Just as a heads up, once rights have propagated, I will be removing any comments by you that I
perceive to be rude (hint: "how the f**k" is rude).
There are good arguments in favor of giving -9223372036854775808 special treatment and some
languages do so (I think Java does). There are also good reasons to not give it special treatment
and some languages do so (C and C++ definitely do). You argue none of that and instead post
disrespectful and inflammatory comments -- and keep doing that across many different bug reports.
If you wish your comments to remain in the future, please temper the manner in which you express
your concerns or feedback.
------------------------------------------------------------------------
[2018-05-29 12:53:36] ajf@php.net
PHP has for the longest time automatically converted to float if an integer becomes too big to
represent with the native machine size (64-bit or 32-bit).
php > var_dump(PHP_INT_MAX);
int(9223372036854775807)
php > var_dump(PHP_INT_MAX + 1);
float(9.2233720368548E+18)
Whether this is good or not depends on your perspective. It looses some accuracy (the least
significant digits), but you at least know the most significant digits and the exponent of the
number. Overflow (when an integer becomes too big) is a problem that inevitably must be solved
somehow. Other options would be to throw an error or exception, or to convert to a (slow, software)
arbitrary-precision integer type. Those have their own disadvantages.
Overflow creates trouble here because
- in PHP is not a negative sign, it is a negation
operator. PHP does not have negative number literals; in PHP, -123 is actually
-(123) â you create a positive number (123) then immediately negate it (-). This
is fine for every case bar one: two's complement integers are unfortunately asymmetrical, so
you can't get the minimum integer value (-9223372036854775808 for 64-bit) just by negating
9223372036854775808, since 9223372036854775808 is greater than PHP_INT_MAX (9223372036854775807):
php > var_dump(PHP_INT_MIN);
int(-9223372036854775808)
php > var_dump(9223372036854775808);
float(9.2233720368548E+18)
php > var_dump(-9223372036854775808);
float(-9.2233720368548E+18)
You can, however, negate PHP_INT_MAX and then subtract one (-PHP_INT_MAX - 1), since no overflow
happens there:
php > var_dump(-PHP_INT_MAX - 1);
int(-9223372036854775808)
Similarly you can do a bitwise NOT:
php > var_dump(~PHP_INT_MAX);
int(-9223372036854775808)
But these days the best option is to use the new PHP_INT_MIN constant that was added in PHP 7.0:
php > var_dump(PHP_INT_MIN);
int(-9223372036854775808)
Overflow resulting in a float is a deliberate feature, and - negating instead of
marking a negative number is also deliberate, so this is expected behaviour and therefore not a bug.
It's not great, for sure, but there's not a nice clean way to âfixâ it since
it's a consequence of several features working as intended. Incidentally, overflow here is a
problem common to other C-like languages that lack negative number literals. Whether PHP handles it
better than those other languages is an interesting question.
------------------------------------------------------------------------
[2018-05-29 12:52:21] spam2 at rhsoft dot net
this is unaccepatble because "$class->property = -9223372036854775808" while even
don't know that the value *is* PHP_INT_MIN must not end as float in a strict-typed application
php > echo PHP_INT_MIN;
-9223372036854775808
php > echo is_int(PHP_INT_MIN);
1
php > $x = -9223372036854775808;
php > echo is_float($x);
1
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=53934
--
Edit this bug report at https://bugs.php.net/bug.php?id=53934&edit=1