Skip to content

Parsing literal assignment of min int64 is not an integer (-9223372036854775808) #14589

Closed
@lewismoten

Description

@lewismoten

Description

I'm testing some edge cases with my code and started tracing a problem down to PHP itself. It turns out that assigning the minimum value of a 64 bit signed integer as a literal value ( -9223372036854775808) to a variable is not recognized as an integer. However, minimum value + 1 (-9223372036854775807) is recognized as an integer. In addition, the PHP_INT_MIN constant with the same value is recognized as an integer. Something is going on with the interpretation of numeric literals for only this specific value.

Furthermore, if I start with assigning a variable the minimum value - 1 (ie $value = -9223372036854775807 -1), then the minimum 64 bit signed value is correctly interpreted as an integer.

The following code:

<?php
error_reporting(E_ALL);

function foo(int $value) {
    return "Yes!";
}

echo "PHP Version: ".PHP_VERSION."<br>";

echo "Minimum value: ".PHP_INT_MIN."<br>"; // -9223372036854775808
echo "is_int: ".is_int(PHP_INT_MIN)."<br>";
echo "gettype: ".gettype(PHP_INT_MIN)."<br>";
echo "binary: 0x". strtoupper(unpack('H*', pack('J', PHP_INT_MIN))[1])."<br>";
try {
    echo "function worked: " . foo(PHP_INT_MIN)."<br>";
} catch (Exception $e) {
    echo "function failed: ".$e->getMessage()."<br>";
}
echo "<br>";

echo "PHP_INT_MIN assignment to variable<br>";
$value = PHP_INT_MIN;
echo "number: PHP_INT_MIN<br>";
echo "variable: ".$value."<br>";
echo "is_int: ".is_int($value)."<br>";
echo "gettype: ".gettype($value)."<br>";
echo "binary: 0x". strtoupper(unpack('H*', pack('J', $value))[1])."<br>";
try {
    echo "function type declaration passed: " . foo($value)."<br>";
} catch (Exception $e) {
    echo "function type declaration failed: ".$e->getMessage()."<br>";
}
echo "<br>";

echo "Hard-coded/literal assignment of -9223372036854775808 to variable<br>";
$value = -9223372036854775808;
echo "number: -9223372036854775808<br>";
echo "variable: ".$value."<br>"; // -9.2233720368548E+18 ?
echo "is_int: ".is_int($value)."<br>"; // false?
echo "gettype: ".gettype($value)."<br>"; // double?
echo "binary: 0x". strtoupper(unpack('H*', pack('J', $value))[1])."<br>";
try {
    echo "function type declaration passed: " . foo($value)."<br>";
} catch (Exception $e) {
    echo "function type declaration failed: ".$e->getMessage()."<br>";
}
echo "<br>";

$value = -9223372036854775807;
echo "test: minimum signed int64 + 1<br>";
echo "number: -9223372036854775807<br>";
echo "variable: ".$value."<br>";
echo "is_int: ".is_int($value)."<br>";
echo "gettype: ".gettype($value)."<br>";
echo "binary: 0x". strtoupper(unpack('H*', pack('J', $value))[1])."<br>";
try {
    echo "function type declaration passed: " . foo($value)."<br>";
} catch (Exception $e) {
    echo "function type declaration failed: ".$e->getMessage()."<br>";
}
echo "<br>";

$value = -9223372036854775807 - 1;
echo "test: minimum signed (int64 + 1) - 1<br>";
echo "number: -9223372036854775808<br>";
echo "variable: ".$value."<br>";
echo "is_int: ".is_int($value)."<br>";
echo "gettype: ".gettype($value)."<br>";
echo "binary: 0x". strtoupper(unpack('H*', pack('J', $value))[1])."<br>";
try {
    echo "function type declaration passed: " . foo($value)."<br>";
} catch (Exception $e) {
    echo "function type declaration failed: ".$e->getMessage()."<br>";
}
?>

Resulted in this output:

PHP Version: 8.3.6
Minimum value: -9223372036854775808
is_int: 1
gettype: integer
binary: 0x8000000000000000
function worked: Yes!

PHP_INT_MIN assignment to variable
number: PHP_INT_MIN
variable: -9223372036854775808
is_int: 1
gettype: integer
binary: 0x8000000000000000
function type declaration passed: Yes!

Hard-coded/literal assignment of -9223372036854775808 to variable
number: -9223372036854775808
variable: -9.2233720368548E+18
is_int:
gettype: double
binary: 0x8000000000000000
function type declaration passed: Yes!

test: minimum signed int64 + 1
number: -9223372036854775807
variable: -9223372036854775807
is_int: 1
gettype: integer
binary: 0x8000000000000001
function type declaration passed: Yes!

test: minimum signed (int64 + 1) - 1
number: -9223372036854775808
variable: -9223372036854775808
is_int: 1
gettype: integer
binary: 0x8000000000000000
function type declaration passed: Yes!

But I expected this output instead:

PHP Version: 8.3.6
Minimum value: -9223372036854775808
is_int: 1
gettype: integer
binary: 0x8000000000000000
function worked: Yes!

PHP_INT_MIN assignment to variable
number: PHP_INT_MIN
variable: -9223372036854775808
is_int: 1
gettype: integer
binary: 0x8000000000000000
function type declaration passed: Yes!

Hard-coded/literal assignment of -9223372036854775808 to variable
number: -9223372036854775808
variable: -9223372036854775808
is_int: 1
gettype: integer
binary: 0x8000000000000000
function type declaration passed: Yes!

test: minimum signed int64 + 1
number: -9223372036854775807
variable: -9223372036854775807
is_int: 1
gettype: integer
binary: 0x8000000000000001
function type declaration passed: Yes!

test: minimum signed (int64 + 1) - 1
number: -9223372036854775808
variable: -9223372036854775808
is_int: 1
gettype: integer
binary: 0x8000000000000000
function type declaration passed: Yes!

PHP Version

8.3.6

Operating System

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions