php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #45953 Sign-Bit Manipulating is buggy
Submitted: 2008-08-30 10:23 UTC Modified: 2008-08-30 11:15 UTC
From: ben at umingo dot de Assigned:
Status: Not a bug Package: Output Control
PHP Version: 5.2.6 OS: Windows XP 32Bit
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: ben at umingo dot de
New email:
PHP Version: OS:

 

 [2008-08-30 10:23 UTC] ben at umingo dot de
Description:
------------
Problem is with sign bit. 
If i have 0x81234567 then first bit is set to 1 (sign bit).
I would expect that number to be negative, as all integers are signed 32 bit integers. 
If i echo that number, it is positive!
If i compute something with this number, it turns negative!

I have a standard PHP 5.2.6 Version and did not modify anything at it.



Reproduce code:
---------------
<?
//sign bit is not handled correctly

//a | a is expected to be a ...
//WORKS NOT
echo "with sign bit <br>";
echo (0x81234567 | 0x81234567); //result is negative
echo "<br>";
echo (0x81234567 );//result is positive

echo "<br>without sign bit <br>";
//WORKS
echo (0x71234567 | 0x71234567);
echo "<br>";
echo (0x71234567 );
?>

Expected result:
----------------
with sign bit 
-2128394905
-2128394905
without sign bit 
1898136935
1898136935


Actual result:
--------------
with sign bit 
-2128394905
2166572391
without sign bit 
1898136935
1898136935


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-08-30 11:15 UTC] mattwil@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

What's happening is that when the script is parsed and compiled, 0x81234567 actually becomes a float/double type since, as you mention, it's too big for 32-bit signed range and the intended behavior is to keep it positive (as it would be on platforms with 64-bit longs) and not restrict it to integer type only. The bitwise operators like | only operate on integers, and it converts a float/double to int first, which results in "overflow" to a negative number that you're seeing.

Typecasting to (int) will also force the overflow (same internal conversion used by bitwise operators), and give the result you expect (on 32-bit platform anyway). Example:

<?php

var_dump(0x81234567);
var_dump(0x81234567 | 0x81234567);
var_dump((int) 0x81234567);


Output:

float(2166572391)
int(-2128394905)
int(-2128394905)
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Mon May 12 05:01:28 2025 UTC