Doc #53934 [ReO->Csd]: The negative PHP_INT_MAX is incorrectly converted to float

From: 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&amp;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

« previous php.doc.bugs (#15726) next »