简体   繁体   English

PHP-需要对is_int()和while循环进行说明

[英]PHP - need clarification on is_int() and while loop

I want to convert a decimal number to an integer by multiplying it by 10 until it gives me an integer. 我想将十进制数乘以10,直到得到整数,将其转换为整数。

Example: 0.2 should become 2 and 0.004 should become 4 示例:0.2应该变成2,0.004应该变成4

Here is my function 这是我的功能

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

I want 我想要

make_integer(0.2) => 2

Shouldn't the function stop when $temp becomes an integer? $ temp变成整数时函数不应该停止吗? The function seems to be going in an infinite loop. 该函数似乎处于无限循环中。

Could someone tell me why this isn't working please? 有人可以告诉我为什么这不起作用吗?

Short answer 简短答案

This will solve your problem 这将解决您的问题

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

Long Answer 长答案

The problem is that is_int does not test if your value is an integer or not. 问题是is_int不会测试您的值是否为整数。 It will test if its type is an integer or not. 它将测试其类型是否为整数。 So is_int($var) will do the same as if you ran gettype($var) == 'integer' . 所以is_int($var)的作用与您运行gettype($var) == 'integer'

Some basic tests: 一些基本测试:

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

To make your code work, and to test if a value is an integer, you should cast your variable to an integer and then test if it is still equal to the original variable, like this: 为了使代码工作并测试是否为整数,应将变量转换为整数,然后测试其是否仍等于原始变量,如下所示:

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

To fix your code, substitute the !is_int($num) with (int) $num != $num and !is_int($temp) with (int) $temp != $temp , just like the code in the short answer above. 要修复您的代码,将!is_int($num)替换为(int) $num != $num并将!is_int($temp)替换为(int) $temp != $temp ,就像上面简短回答中的代码一样。

But, I can't resist to give an alternative solution to your problem. 但是,我无法抗拒为您的问题提供替代解决方案。 Personally, I would opt to use recursion for this problem. 就个人而言,我会选择对这个问题使用递归。 Like this: 像这样:

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

Or if you dislike the ternary operator: 或者,如果您不喜欢三元运算符:

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
}

Even longer answer 更长的答案

The type casting of php will take some time to learn. php的类型转换将需要一些时间来学习。 In general, PHP will allways try to type cast if it can. 通常,PHP将尽可能尝试键入强制类型转换。 When you multiply an integer with a float, the result will be a float, even if it "looks" like an integer. 当您将整数与浮点数相乘时,即使它看起来像整数,结果也将是浮点数。

So try this code and pay special attention to the output: 因此,请尝试以下代码并特别注意输出:

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

Now, if you multiply by the integer 100, php will stick the float, as <float>*<int> multiplication allways will result in a float, regardless of the value. 现在,如果您将整数乘以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)

Note that the value is a natural number, but the type is still a float, and thus is_int will not return true. 请注意,该值是自然数,但类型仍然是浮点数,因此is_int不会返回true。

To test if a actual value of a variable is indeed an integer, we will need to do our own little trick with manual typecasting. 要测试变量的实际是否确实是整数,我们将需要通过手动类型转换来做一些自己的小技巧。

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

Note that when we tried to cast a float to an int the value changed. 请注意,当我们尝试将float转换为int时,值已更改。 But if we try to cast a float that is an integer to an int, the value remains unaffected, only the type gets changed: 但是,如果我们试图施放浮动为int的整数,价值不受影响,只有类型得到改变:

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

And now, remember how <int>*<float> resulted in a float? 现在,还记得<int>*<float>导致浮点吗? PHP will work in the same way when you do comparisons. 比较时,PHP将以相同的方式工作。 In php, "2.0" == 2 will be true because of this automatic typecasting. 在php中,由于此自动类型转换,因此"2.0" == 2将为true So when you do <int> == <float> what really happens is (float)<int> == <float> . 因此,当您执行<int> == <float> ,真正发生的是(float)<int> == <float>

So what happens if we do (float)(int)0.3 . 那么如果我们执行(float)(int)0.3会发生什么。 First we typecast 0.3 to int(0), then we typecast back to float(0). 首先我们将0.3转换为int(0),然后将其转换回为float(0)。 Obviously, float(0) == float(0.3) will be false . 显然, float(0) == float(0.3)将为false But (float)(int)3.0 will be cast first to int(3) then to float(3), which was the same value we started with. 但是(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)

So if we do (int) 3.0 == 3.0 , it will result in (float)(int) 3.0 == 3.0 which is true . 因此,如果我们执行(int) 3.0 == 3.0 ,则将导致(float)(int) 3.0 == 3.0 ,这是true

So the way to test if a value is integer is to do 因此,测试值是否为整数的方法是

(int)$var == $var

answer: 回答:

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

to resolve your problem, change the logic test. 要解决您的问题,请更改逻辑测试。

  • (int) $i == $i (int)$ i == $ i

This isn't the prettiest but it works. 这不是最漂亮,但可以。

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM