我认为不再需要担心尾随空字符了。这个问题在2002年2月已修复(参见bug 10133)
(PHP 4 >= 4.0.4, PHP 5, PHP 7, PHP 8)
gmp_strval — 将GMP数转换为字符串
num
将被转换为字符串的GMP数。
一个GMP 对象,一个int,或一个string,可以解释为数字,其逻辑与在gmp_init()中使用字符串进行自动基数检测相同(即,当base
等于0时)。
base
返回数字的基数。默认基数为10。基数的允许值为2到62和-2到-36。
数字,作为string。
示例 #1 将GMP数转换为字符串
<?php
$a = gmp_init("0x41682179fbf5");
printf("十进制: %s, 36进制: %s", gmp_strval($a), gmp_strval($a,36));
?>
值得注意的是,对于大数,使用gmp_strval可能会大大降低脚本速度。
例如,这段脚本依次生成阶乘
<?php
$start = microtime(TRUE);
$fact = gmp_init(1, 10);
for($i=1;$i<100000;$i++) { // 计算100,000个阶乘
$fact = gmp_mul($fact, $i); // $fact现在是第$i个阶乘的结果
// gmp_strval($fact, 10); // 见下文...
if(microtime(TRUE)-$start>1) // 1秒后停止计算
break;
}
// 打印耗时1秒完成的任何结果
printf("\$i = %d\n\$fact = %s\n", gmp_strval($fact, 10));
?>
我的服务器平均每次计算大约69,500次阶乘。取消对该gmp_strval行的注释会大大降低此过程的速度,并且只计算大约5,000个阶乘。这大约比以前慢14倍(这与允许它运行任意秒数一致,而不仅仅是1秒)。
Nitrogen。
在关联数组中使用gmp_strval的值作为键时的一个陷阱。某些数字2^31被转换为有符号整数格式,这通常是不正确的。
<?php
$a = gmp_init('2147483649'); // = 2^31 + 1
$b = gmp_init('3173604585'); // = 2^31 < $b < 2^32
$c = gmp_strval($a);
$d = gmp_strval($b);
$e = array($c => 'c', $d => 'd');
print '*** 预期 '."\n";
print '数组 '."\n".'('."\n".' ['.$c.'] => c'."\n".' ['.$d.'] => d'."\n".')'."\n\n";
print '*** 实际 '."\n";
print_r($e);
?>
输出
*** 预期
数组
(
[2147483649] => c
[3173604585] => d
)
*** 实际
数组
(
[-2147483647] => c
[3173604585] => d
)
一种解决方法是格式化为16进制,并在使用作为键之前附加'0x'。
警告:gmp_strval 函数可能返回一个以 null 结尾的字符串(例如,gmp_strval(gmp_init(8)) 有两个字符)。这是因为 GMP 为了速度而构建,所以它使用基于它可以快速获取的信息(例如 N 的位数)的估计值。因此,由于 8 是一个 4 位数,它将被分配 ceil(log10(2^4))=ceil(4*0.30103....) = 2 个字符。GMP 开发人员认为检查是否需要所有字符是调用者的责任(在本例中是 PHP 接口)。PHP 本来可以为我们做到这一点(将来也可能会这样做),但目前,您需要检查(如果这对您很重要——在我的程序中确实很重要!)。