Question

I want to convert a decimal number to an integer by multiplying it by 10 until it gives me an integer.

Example: 0.2 should become 2 and 0.004 should become 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? The function seems to be going in an infinite loop.

Could someone tell me why this isn't working please?

Was it helpful?

Solution

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. 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'.

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.

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. In general, PHP will allways try to type cast if it can. 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.

$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.

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. But if we try to cast a float that is an integer to an int, the value remains unaffected, only the type gets changed:

$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? PHP will work in the same way when you do comparisons. In php, "2.0" == 2 will be true because of this automatic typecasting. So when you do <int> == <float> what really happens is (float)<int> == <float>.

So what happens if we do (float)(int)0.3. First we typecast 0.3 to int(0), then we typecast back to float(0). Obviously, float(0) == float(0.3) will be 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.

$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.

So the way to test if a value is integer is to do

(int)$var == $var

OTHER TIPS

answer:

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

to resolve your problem, change the logic test.

  • (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);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top