Bug #74748 [Com]: HexDec outputs invalid conversions

From: Date: Mon, 12 Jun 2017 11:33:27 +0000
Subject: Bug #74748 [Com]: HexDec outputs invalid conversions
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-209502@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=74748&edit=1 ID: 74748 Comment by: danack@php.net Reported by: sysop at pkx dot pw Summary: HexDec outputs invalid conversions Status: Not a bug Type: Bug Package: Math related Operating System: LInux Mint 18 PHP Version: Irrelevant Block user comment: N Private report: N New Comment: > -9223372036854775808 is the same as the defined PHP_INT_MIN. echo dechex(-9223372036854775808); // 8000000000000000 which is the same as PHP_INT_MAX + 1. HexDec has no way of knowing which one you meant. > I guess as a whole php only supports unsigned numbers. No, in this very particular case PHP can't tell the difference. > I have try'ed to use pack with the q syntax however it outputs a invalid hexadecimal > number as a whole, so thats wrong too. $packed = pack('J', -9223372036854775805); echo bin2hex($packed) . "\n"; var_dump(unpack('Jfoo', $packed)); // Output is 8000000000000003 array(1) { ["foo"]=> int(-9223372036854775805) } Please feel free to report a separate bug if you can make a reproduce case. Previous Comments: ------------------------------------------------------------------------ [2017-06-12 10:10:32] sysop at pkx dot pw This is clearly a bug, -9223372036854775808 is the same as the defined PHP_INT_MIN. I need to keep the signedness of the variable, but I guess as a whole php only supports unsigned numbers. What I mean is your correct some weirdness goes on, as the defined value is output as a integer, but the same value as a variable outputs a float, even through they're the same number. I have try'ed to use pack with the q syntax however it outputs a invalid hexadecimal number as a whole, so thats wrong too. ------------------------------------------------------------------------ [2017-06-12 09:35:31] danack@php.net You are converting decimal to hex, which converts the number to the representation, but doesn't save the signed information. $hexed = dechex(-9223372036854775805); var_dump($hexed); var_dump(dechex(PHP_INT_MAX)); //Output is string(16) "8000000000000003" string(16) "7fffffffffffffff" When PHP goes to convert back from this string, to a decimal, it interprets 0x80000000003 as an unsigned number. As that number is bigger than PHP_INT_MAX, it overflows to a floating point number, where weird things start happening, as not every int can be represented in a float above 2**53. Perhaps you want to be using the pack and unpack functions: http://php.net/manual/en/function.pack.php http://php.net/manual/en/function.unpack.php Which shouldn't make assumptions about the signedness of numbers. ------------------------------------------------------------------------ [2017-06-12 08:38:46] sysop at pkx dot pw Description: ------------ --- From manual page: http://www.php.net/function.hexdec --- Test script: --------------- var_dump((int)hexdec(dechex(-9223372036854775805))); var_dump((int)hexdec(dechex(-9223372036854775804))); var_dump((int)hexdec(dechex(-9223372036854775803))); Expected result: ---------------- int(-9223372036854775808) int(-9223372036854775808) int(-9223372036854775808) ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=74748&edit=1

« previous php.bugs (#209502) next »