Php convert signed integer to unsigned

It appears, that in 32bit OS ip2long returns signed int, and in 64bit OS unsigned int is returned.

My application is working on 10 servers, and some are 32bit and some are 64bit, so I need all them to work same way.

In PHP documentation there is a trick to make that result always unsigned, but since I got my database already full of data, I want to have it signed.

So how to change an unsigned int into a signed one in PHP?

asked May 16, 2009 at 13:19

1

PHP does not support unsigned integers as a type, but what you can do is simply turn the result of ip2long into an unsigned int string by having sprintf interpret the value as unsigned with %u:

 $ip="128.1.2.3";
 $signed=ip2long[$ip];             // -2147417597 in this example
 $unsigned=sprintf["%u", $signed]; //  2147549699 in this example

Edit, since you really wanted it to be signed even on 64 bit systems - here's how you'd convert the 64 bit +ve value to a 32 bit signed equivalent:

$ip = ip2long[$ip];
if [PHP_INT_SIZE == 8]
{
    if [$ip>0x7FFFFFFF]
    {
        $ip-=0x100000000;
    }
}

answered May 16, 2009 at 14:01

Paul DixonPaul Dixon

290k50 gold badges309 silver badges344 bronze badges

3

Fwiw, if you're using MySQL it's usually a lot easier and cleaner if you just pass in the IPs as strings to the database, and let MySQL do the conversion using INET_ATON[] [when INSERTing/UPDAT[E]'ing] and INET_NTOA[] [when SELECTing]. MySQL does not have any of the problems described here.

Examples:

SELECT INET_NTOA[ip_column] FROM t;

INSERT INTO t [ip_column] VALUES [INET_ATON['10.0.0.1']];

The queries are also much more readable.

Note that you can not mix INET_NTOA[]/INET_ATON[] in MySQL with ip2long[]/long2ip[] in PHP, since MySQL uses an INT UNSIGNED datatype, while PHP uses a signed integer. Mixing signed and unsigned integers will seriously mess up your data!

answered Jan 5, 2010 at 20:33

interpreting an integer value as signed int on 32 and 64 bit systems:

function signedint32[$value] {
    $i = [int]$value;
    if [PHP_INT_SIZE > 4]   // e.g. php 64bit
        if[$i & 0x80000000] // is negative
            return $i - 0x100000000;
    return $i;
} 

answered May 31, 2012 at 22:00

epos_jkepos_jk

2392 silver badges6 bronze badges

-Misunderstood problem, see Paul Dixon's answer above.

64bit unsigned integers are not technically supported in PHP5. It will use the native type. To convert to a 32bit signed int from a 64bit signed int without losing the high bit, you could mask and then type cast the output:

$ip_int = ip2long[$ip];
if [PHP_INT_SIZE == 8] // 64bit native
{
  $temp_int = [int][0x7FFFFFFF & $ip_int];
  $temp_int |= [int][0x80000000 & [$ip_int >> 32]];
  $ip_int = $temp_int;
}

On a 64 bit system, printing this value [$ip_int] will display an 'unsigned' integer since we've removed the high bit. However this should allow you to take the output and store it how you wish.

answered May 16, 2009 at 14:14

cyberbillcyberbill

1141 silver badge7 bronze badges

4

public function unsigned2signed[$num] {     // converts unsigned integer to signed
    $res = pack['i',$num];                  // change to 'l' to handle longs
    $res = unpack['i',$res][1];
    return $res;
}

answered Jul 5, 2021 at 21:26

atyachinatyachin

1,0231 gold badge12 silver badges14 bronze badges

unsigned-int is a php library to convert signed integers to unsigned. [Disclaimer: I'm the author]

use Oct8pus\Unsigned\UInt32;

require_once './vendor/autoload.php';

$uint32 = new UInt32[-2147483648];
echo $uint32;
-2147483648 > 0x80000000 [2147483648]

The repository is here //github.com/8ctopus/unsigned-int

answered Jul 14 at 5:54

8ctopus8ctopus

1,8942 gold badges13 silver badges20 bronze badges

Not the answer you're looking for? Browse other questions tagged php math absolute-value or ask your own question.

Chủ Đề