spidEY
spidEY

Reputation: 944

Unexpected behavior in PHP - Same code gives correct results in C# and Python

Why does PHP return INF (infinity) for the following piece of code:

<?php
$n = 1234;
$m = 0;

while ($n > 0)
{
    $m = ($m * 10) + ($n % 10);
    $n = $n / 10;
}

var_dump($m);
?>

The expected result was 4321, but PHP returned INF, float type:

float INF

I wrote the same code in Python and C# and got the expected output - 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();
}

Upvotes: 16

Views: 541

Answers (6)

Marius
Marius

Reputation: 1073

What is happening is that:

$n = $n / 10;

Is performing float division instead of integer division, thus $n never reaches a value of 0, it just approaches a value of 0, i.e. 0.0...1234.

Changing the above code to this:

$n = (int)($n / 10);

Will fix the problem.

Upvotes: 5

Victor Dramba
Victor Dramba

Reputation: 121

the correct algoritm uses floor()

<?php
$n = 1234;
$m = 0;

while ($n > 0)
{
    $m = $m * 10 + ($n % 10);
    $n = floor($n / 10);
}

var_dump($m);

Upvotes: 2

Prasanth
Prasanth

Reputation: 5268

$n = intval($n / 10);

That seems to have solved the problem.

Upvotes: 0

xdazz
xdazz

Reputation: 160923

In php $n / 10 will return a float number, not integer.

So $n > 0 will always be true.

Change while($n > 0)

to while($n > 1) or while((int)$n > 0), then you will get the right result.

Upvotes: 13

ATaylor
ATaylor

Reputation: 2598

PHP is typeless and converts 'on the fly'.

That means, you $n will never be '0' or lower, because $n will be a 'float', when needed.

Try checking for < 1, and you should be fine.

Just to clarify this, $n will behave like this:

$n = 1234 $n = 123.4 $n = 12.34 $n = 1.234 $n = 0.1234 $n = 0.01234 etc.

Meaning: $n will always approach 0, but never reach it. That makes $m infinite, since the loop itself is infinite.

Upvotes: 6

Petah
Petah

Reputation: 46060

It is more that likely because of typical floating point arithmetic.

If you use BCMath Arbitrary Precision Mathematics it does not have the same effect.

$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

See also:

http://php.net/manual/en/language.types.float.php

Upvotes: 0

Related Questions