Bug #53934 [Nab]: The negative PHP_INT_MAX is incorrectly converted to float
| From: | nikic@php.net | Date: | Tue, 29 May 2018 12:53:52 +0000 |
| Subject: | Bug #53934 [Nab]: The negative PHP_INT_MAX is incorrectly converted to float | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-215416@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: nikic@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: Not a bug
Type: Bug
Package: Scripting Engine problem
Operating System: Linux
PHP Version: 5.3.5
Block user comment: N
Private report: N
New Comment:
@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.
Previous Comments:
------------------------------------------------------------------------
[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
------------------------------------------------------------------------
[2018-05-29 12:30:50] spam2 at rhsoft dot net
how the f**k is that not a bug and how does http://www.php.net/manual/ justify that gambling machine
behavior?
php > $x = 9223372036854775808;
php > echo is_int($x);
php > $x = (int)9223372036854775808;
php > echo is_int($x);
1
-----
php > $x = 9223372036854775808;
php > echo is_int($x);
php > $x = (int)9223372036854775808;
php > echo is_int($x);
1
------------------------------------------------------------------------
[2018-05-29 12:20:16] ajf@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to
report
a bug at http://bugs.php.net/how-to-report.php
------------------------------------------------------------------------
[2018-05-29 12:18:49] spam2 at rhsoft dot net
come on, explain me why the large number becomes a float when we all known from hundrets of
bugrports that float values are making nothing than trouble swhen you touch or even echo them in
doubt
php > $x = 9223372036854775808;
php > echo is_float($x);
1
php > $x = 922337203685477;
php > echo is_float($x);
php > echo is_int($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