在某些时候我有这段代码:
while( $i> $l-1 )
{
$x= fmod($i,$l);
$i= floor($i/$l);
}
我决定摆脱模运算并写下这个块:
while( true )
{
$d= floor( $i/$l );
if( $d>= 1 )
{
$x= $i - ($d*$l);
$i= $d;
}
else
{
break;
}
}
$ x用于索引长度为$ l的数组。 $ i在这里有问题。
对于一些相对较小的初始$ i,两个块在所有迭代中给出相同的$ x,当用接近PHP_INT_MAX的东西初始化时,两个块不会给出相同的$ x。
不幸的是,为了使用位操作符,$ l不能成为2的幂,所以我坚持这个。
我猜这与发生的内部舍入有关。 fmod可以针对这种情况进行优化吗?有什么我没看到的吗?
我应该提到的一件事是,虽然人们会期望第二种方法能够产生更好的结果,但是由于使用了简单的减法,它却没有。可能是因为在循环开始时发生了分裂。(这就是为什么我问" fmod可以如此优化)。
答案 0 :(得分:1)
根据文档,fmod
适用于花车:
fmod - 返回参数除法的浮点余数(模数)
相反,modulo operator (%
)更适合您的需求:
在处理之前,模数的操作数被转换为整数(通过去除小数部分)。
fmod
对于大整数将变得不准确,因为浮点表示不具有相同的精度。
发生一些奇怪的例子:
$l=3;
$i=9223372036854775295;
echo is_int($i) . "<br>"; // 1 (true)
echo (9223372036854775295==$i) . "<br>"; // 1 (true)
echo number_format($i, 0, ".", "") . "<br>"; // 9223372036854774784
echo fmod($i,$l) . "<br>"; // 1
echo fmod($i-1,$l) . "<br>"; // 1
echo fmod($i-2,$l) . "<br>"; // 1
echo ($i % $l) . "<br>"; // 2
echo (($i-1) % $l) . "<br>"; // 1
echo (($i-2) % $l) . "<br>"; // 0
注意一个简单的number_format
如何破坏整数的精度;由于浮点转换,它返回不同的数字。
另请注意,这种精确度的缺失会导致fmod
连续三个数字返回1,而模运算符会执行您想要的操作。
所以你似乎对%
好多了。
您的功能似乎将数字分解为&#34;数字&#34;以L为基础。例如,当$l=2
时,您的$x
- 序列生成数字的二进制表示形式,除了您遗漏的最后一位数字。
在这方面,您可以查看函数调用base_convert($i,10,$l)
,它会在代码中生成一个与$x
值对应的数字,数字字母大于9。函数可以接受最多36个$l
值。