我认为不再需要担心尾部空字符。这在 2002 年 2 月修复了(参见错误 10133)
(PHP 4 >= 4.0.4, PHP 5, PHP 7, PHP 8)
gmp_strval — 将 GMP 数字转换为字符串
数字,以 string 格式。
示例 #1 将 GMP 数字转换为字符串
<?php
$a = gmp_init("0x41682179fbf5");
printf("Decimal: %s, 36-based: %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 '*** Expect '."\n";
print 'Array '."\n".'('."\n".' ['.$c.'] => c'."\n".' ['.$d.'] => d'."\n".')'."\n\n";
print '*** Actual '."\n";
print_r($e);
?>
输出
*** Expect
Array
(
[2147483649] => c
[3173604585] => d
)
*** Actual
Array
(
[-2147483647] => c
[3173604585] => d
)
一个解决方法是在使用它作为键之前将其格式化为 16 进制并添加 '0x'。
警告:gmp_strval 可能会返回一个以空字符结尾的字符串(例如,gmp_strval(gmp_init(8)) 有两个字符。这是因为 gmp 为了速度而构建,因此使用基于它可以快速获取的估计值,例如 N 的位数。所以,由于 8 是一个 4 位数字,它将被分配 ceil(log10(2^4))=ceil(4*0.30103....) = 2 个字符。gmp 人员认为检查是否需要所有字符是调用者的责任(在本例中是 PHP 接口)。PHP 可能会为我们完成此事(将来也可能会),但现在,您需要检查(如果您需要这样做 - 在我的程序中确实需要这样!)。