PHP中的Unsigned int

xxhby3vn  于 2023-05-05  发布在  PHP
关注(0)|答案(7)|浏览(213)

在32位操作系统中,ip2long返回有符号的int,而在64位操作系统中,返回无符号的int。
我的应用程序是工作在10台服务器上,有些是32位,有些是64位,所以我需要所有的工作方式相同。
在PHP文档中,有一个技巧可以使结果总是无符号的,但是因为我的数据库已经充满了数据,所以我想让它签名。
如何在PHP中将unsigned int转换为signed int?

w8ntj3qf

w8ntj3qf1#

PHP不支持unsigned integers作为类型,但你可以做的是简单地将ip2long的结果转换为unsigned int string,方法是让sprintf使用%u将值解释为unsigned:

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

ajsxfq5m2#

Fwiw,如果你使用MySQL,如果你只是将IP作为字符串传递给数据库,让MySQL使用INET_ATON()(当INSERT/UPDAT(E)'ing时)和INET_NTOA()(当SELECTing时)进行转换,通常会更容易和更干净。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中的ip 2long()/long 2 ip(),因为MySQL使用INT UNSIGNED数据类型,而PHP使用有符号**整数。混合使用有符号和无符号整数会严重扰乱你的数据!

zhte4eai

zhte4eai3#

在32位和64位系统上将整数值解释为有符号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;
}
kgsdhlau

kgsdhlau4#

  • 被误解的问题,见上面保罗狄克逊的答案。
    64位无符号整数在PHP5中不受技术支持。它将使用本机类型。要从64位有符号整型转换为32位有符号整型而不丢失高位,您可以掩码然后键入强制转换输出:
$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)将显示一个“无符号”整数,因为我们已经删除了高位。但是,这应该允许您按照自己的意愿获取输出并存储它。

sg24os4d

sg24os4d5#

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

ds97pgxw6#

unsigned-int是一个php库,用于将有符号整数转换为无符号整数。(免责声明:我是作者)

use Oct8pus\Unsigned\UInt32;

require_once './vendor/autoload.php';

$uint32 = new UInt32(-2147483648);
echo $uint32;
-2147483648 > 0x80000000 (2147483648)

仓库在这里https://github.com/8ctopus/unsigned-int

2wnc66cl

2wnc66cl7#

静态转换为32位有符号整数。适用于64位和32位PHP。

function toSInt32($a) {
  return ~0x7FFFFFFF * (($a >> 31) & 1) + ($a & 0x7FFFFFFF);
}

--------

var_dump(toSInt32(0));
var_dump(toSInt32(1));
var_dump(toSInt32(0x7FFFFFFF));
var_dump(toSInt32(0x80000000));
var_dump(toSInt32(0x8000000000));
var_dump(toSInt32(0xFFFFFFFF));
var_dump(toSInt32(0xFFFFFFFFFF));

--------

int(0)
int(1)
int(2147483647)
int(-2147483648)
int(0)
int(-1)
int(-1)

相关问题