PHP - 需要澄清 is_int() 和 while 循环

Posted

技术标签:

【中文标题】PHP - 需要澄清 is_int() 和 while 循环【英文标题】:PHP - need clarification on is_int() and while loop 【发布时间】:2013-08-02 19:36:57 【问题描述】:

我想将一个十进制数乘以 10 直到得到一个整数。

示例: 0.2 应该变成 2 并且 0.004 应该变成 4

这是我的功能

function make_integer($num)
    if (!is_int($num))
        $temp = $num;
        while (!is_int($temp))
            $temp *= 10;
        
        return $temp;
    
    return $num;

我想要

make_integer(0.2) => 2

当 $temp 变成整数时,函数不应该停止吗? 该函数似乎进入了无限循环。

有人能告诉我为什么这不起作用吗?

【问题讨论】:

每次打印出$temp,看看循环期间的值是多少 它没有打印任何东西。它只是一直加载一个空白屏幕。 很有趣...我刚刚在我的网站上运行了这个。调试中也没有响应检查那里。如果你去掉中间的循环,你会更进一步,但是...... @Steve 中间循环是什么意思?函数中只有一个循环 @CodingStudent - 是的,我指的是结构中的中间部分,而不是 1,2,3 :) 漫长的一天 【参考方案1】:

简答

这会解决你的问题

function make_integer($num)
    if ((int)$num != $num)
        $temp = $num;
        while ((int)$temp != $temp)
            $temp *= 10;
        
        return $temp;
    
    return $num;

长答案

问题在于is_int 不会测试您的值是否为整数。它将测试其 type 是否为整数。所以is_int($var) 的作用与运行gettype($var) == 'integer' 相同。

一些基本测试:

is_int((int) 0.57); # returns true, because the type is an int.
is_int((float) 4); # returns false, because the type is a float
is_int(10 * 0.2); # returns false, because int*float will be typecasted to a float

要使您的代码正常工作,并测试 value 是否为整数,您应该将变量转换为整数,然后测试它是否仍等于原始变量,如下所示:

(int) $var == $var; # will return true if the value is int

要修复您的代码,请将!is_int($num) 替换为(int) $num != $num 并将!is_int($temp) 替换为(int) $temp != $temp,就像上面简短答案中的代码一样。

但是,我忍不住要为您的问题提供替代解决方案。就个人而言,我会选择使用递归来解决这个问题。像这样:

function make_integer($num) 
    return (int)$num == $num ? $num : make_integer($num * 10);

或者如果你不喜欢三元运算符:

function make_integer($num) 
    if ((int)$num == $num)
        return $num; # We're all done!
    else
        return make_integer($num * 10); # Try to increase by 10

更长的答案

php的类型转换需要一些时间来学习。一般来说,如果可以的话,PHP 总是会尝试进行类型转换。当您将整数与浮点数相乘时,结果将是浮点数,即使它“看起来”像整数。

所以试试这段代码,并特别注意输出:

$var = 0.03;
var_dump($var); # float(0.03)
var_dump(gettype($var)); # string(6) "double"
var_dump(is_int($var)); # bool(false)

现在,如果你乘以整数 100,php 将保留浮点数,因为 <float>*<int> 乘法总是会导致浮点数,无论值如何。

$var *= 100; # (100 * 0.03)
var_dump($var); # float(3)
var_dump(gettype($var)); # string(6) "double"
var_dump(is_int($var)); # bool(false)

注意该值是自然数,但类型仍然是浮点数,因此 is_int 不会返回 true。

要测试一个变量的实际 是否确实是一个整数,我们需要通过手动类型转换来做我们自己的小技巧。

$var = 2.33;
var_dump($var); # float(2.33)
$var = (int) $var;
var_dump($var); # int(2)

请注意,当我们尝试将 float 转换为 int 时,值发生了变化。但是,如果我们尝试将 整数的浮点数转换为 int,则该值不受影响,只有 类型 被更改:

$var = 2.0;
var_dump($var); # float(2)
$var = (int) $var;
var_dump($var); # int(2)

现在,还记得<int>*<float> 是如何产生浮动的吗?当您进行比较时,PHP 将以相同的方式工作。在 php 中,"2.0" == 2 将是 true,因为这种自动类型转换。因此,当您执行<int> == <float> 时,真正发生的是(float)<int> == <float>

如果我们执行(float)(int)0.3 会发生什么。首先我们将 0.3 类型转换为 int(0),然后我们将类型转换回 float(0)。显然,float(0) == float(0.3) 将是 false。但是(float)(int)3.0 将首先转换为 int(3),然后转换为 float(3),这与我们开始使用的值相同。

$var = 3.0;
var_dump($var); # float(3)
$var = (int) $var;
var_dump($var); # int(3)
$var = (float) $var;
var_dump($var); # float(3)

因此,如果我们执行(int) 3.0 == 3.0,它将导致(float)(int) 3.0 == 3.0,即true

所以测试一个值是否为整数的方法是这样做

(int)$var == $var

【讨论】:

很好的解释/答案。我想做一个递归函数,但 php 对我来说是一个新事物。感谢和感谢。 我想我会坚持递归函数,看起来更整洁。真是很好的解释。谢谢【参考方案2】:

回答:

$i=0.0004 ; gettype($i) == 'float' $i*= 10; gettype($i) == 'float' float != int

要解决您的问题,请更改逻辑测试。

(int) $i == $i

【讨论】:

【参考方案3】:

这不是最漂亮的,但它确实有效。

function make_int($num)

    //if it's not an int...
    if(!is_int($num))

        //find out how many decimal places and store in a  variable
        $multiply =  strlen(substr(strrchr($num, "."), 1));

        //multiply the number by the power of the multiple.
            $num *= (pow (10,$multiply));

        return $num;
    


make_int(0.004);

【讨论】:

也想过做同样的事情。我想我将不得不使用这个解决方案,谢谢。任何想法为什么我的原始功能不起作用? 我真的不知道,我标记了 php 以为有人可能会过来解释。只能认为这是因为它被称为。想得太累了:)如果它有效,请点击那个令人惊叹的绿色按钮:)

以上是关于PHP - 需要澄清 is_int() 和 while 循环的主要内容,如果未能解决你的问题,请参考以下文章

PHP is_int 未按预期执行

解决问题第一步:澄清问题之5WHY法寻找根本原因

Kohana3 ORM 需要澄清关系

004 如何定义和澄清问题

需要澄清 mod_rewrite 问题

PHP垃圾收集澄清