为什么PHP为以下代码返回INF(无穷大):
<?php
$n = 1234;
$m = 0;
while ($n > 0)
{
$m = ($m * 10) + ($n % 10);
$n = $n / 10;
}
var_dump($m);
?>
预期结果为4321,但PHP返回INF、浮点类型:
float INF
我用Python和C#编写了相同的代码,并得到了预期的输出-4321
Python
n = 1234
m = 0
while (n > 0):
m = (m * 10) + (n % 10)
n = n / 10
print m
C#
static void Main(string[] args)
{
int n = 1234;
int m = 0;
while (n > 0)
{
m = (m * 10) + (n % 10);
n = n / 10;
}
Console.WriteLine(m);
Console.ReadLine();
}
在php中,$n / 10
将返回一个浮点数,而不是整数。
所以$n > 0
将永远是true
。
更改while($n > 0)
到while($n > 1)
或while((int)$n > 0)
,则会得到正确的结果。
PHP是无类型的,并且可以"动态"转换。
这意味着,$n永远不会是"0"或更低,因为在需要时,$n将是一个"float"。
尝试检查<1,你应该没事的。
为了澄清这一点,$n的行为如下:
$n=1234$n=123.4$n=12.34$n=1.234$n=0.1234$n=0.01234等
意思是:$n将始终接近0,但永远不会达到它。这使得$m是无限的,因为循环本身是无限的。
发生的事情是:
$n = $n / 10;
正在执行浮点除法而不是整数除法,因此$n从未达到值0,它只是接近值0,即0.0…1234。
将上述代码更改为:
$n = (int)($n / 10);
将解决问题。
正确的算法使用floor()
<?php
$n = 1234;
$m = 0;
while ($n > 0)
{
$m = $m * 10 + ($n % 10);
$n = floor($n / 10);
}
var_dump($m);
这更有可能是因为典型的浮点运算。
如果使用BCMath任意精度数学,则不会产生相同的效果。
$n = 1234;
$m = 0;
while ($n > 0)
{
$m = bcmul($m, 10) + bcmod($n, 10);
$n = bcdiv($n, 10);
}
var_dump($m);
http://codepad.viper-7.com/FYNCyN
另请参阅:
http://php.net/manual/en/language.types.float.php
$n = intval($n / 10);
这似乎解决了问题。