unsigned int在php中签名

时间:2009-05-16 13:19:34

标签: php math absolute-value

看来,在32位操作系统ip2long中返回signed int,在64位操作系统中返回unsigned int。

我的应用程序正在处理10台服务器,有些是32位,有些是64位,所以我需要它们以同样的方式工作。

在PHP文档中,有一个技巧可以使结果始终无符号,但由于我的数据库已经充满了数据,我想让它签名。

那么如何在PHP中将unsigned int更改为已签名的?

5 个答案:

答案 0 :(得分:15)

PHP不支持无符号整数作为类型,但您可以做的只是将ip2long的结果转换为unsigned int string ,方法是sprintf解释值为%u无符号:

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

编辑,因为你真的希望它甚至可以在64位系统上进行签名 - 这里是你如何将64位+ ve值转换为32位带符号的等价物:

$ip = ip2long($ip);
if (PHP_INT_SIZE == 8)
{
    if ($ip>0x7FFFFFFF)
    {
        $ip-=0x100000000;
    }
}

答案 1 :(得分:3)

Fwiw,如果你使用MySQL,如果你只是将IP作为字符串传递给数据库,那么通常会更容易和更清洁,让MySQL使用INET_ATON()进行转换(当INSERTing / UPDAT(E)'时) ing)和INET_NTOA()(当选择时)。 MySQL没有任何问题。

示例:

SELECT INET_NTOA(ip_column) FROM t;

INSERT INTO t (ip_column) VALUES (INET_ATON('10.0.0.1'));

查询也更具可读性。

请注意,您可以将MySQL中的INET_NTOA()/ INET_ATON()与PHP中的ip2long()/ long2ip()混合,因为MySQL使用INT UNSIGNED数据类型,而PHP使用签名整数。混合有符号和无符号整数会严重扰乱您的数据!

答案 2 :(得分:2)

在32位和64位系统上将整数值解释为signed int:

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;
} 

答案 3 :(得分:1)

- 明白了问题,请参阅Paul Dixon上面的答案。


PHP5在技术上不支持64位无符号整数。它将使用本机类型。要从64位signed int转换为32位signed int而不丢失高位,您可以屏蔽然后输入转换输出:

$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;
}

在64位系统上,打印此值($ ip_int)将显示“无符号”整数,因为我们已删除高位。但是,这应该允许您获取输出并按照您希望的方式存储它。

答案 4 :(得分:0)

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;
}