# Get Factorial

## Recommended Posts

Hello all, Noob here 😑. Need help in solving this task.

I Wrote a function which returns a factorial number but how to pass the logic that the passing parameter must be an integer. Also, if any other data type is passed, function should return error “Please provide correct data type”.

Many thanks,

```function fact (\$x) {
if(\$x <= 1) {
return 1;
} else  {
return \$x * fact(\$x - 1);
}
}
echo fact(3);    ```

##### Share on other sites
```function fact (\$x) {
if (!ctype_digit("\$x") ) {                             // CAVEAT: cast \$x to string type
}
if(\$x <= 1) {
return 1;
} else  {
return \$x * fact(\$x - 1);
}
}  ```

Edited by Barand
caveat

##### Share on other sites

Minor point. I think the check will catch negative integers since it is cast to a string but the error should say 'Please provide a positive integer".

##### Share on other sites

FWIW, what the task to specifically create a recursive function? If not, you can get a factorial much simpler (of course you'd still want the integer check

`array_product(range(1, \$number));`

##### Share on other sites

Hi @Barand,

I am wondering why you would be introducing strings when this is specifically about int's. IMO is_int should be used instead of ctype_digit.

OP, the else is redundant. You can remove it. Additionally, IMO the int check should not be in the function. The function/method should do one thing and do it well.

As is example

```function fact(\$x)
{
if (!is_int(\$x)) {
}
if (\$x <= 1) {
return 1;
}
return \$x * fact(\$x - 1);
}

echo fact(5);```

Suggested Example

```function fact(int \$x): int
{
return \$x <= 1 ? 1 : \$x * fact(\$x - 1);
}

\$x = 5;
echo is_int(\$x) ? fact(\$x) : 'Please provide an integer';```

Edited by benanamen

##### Share on other sites

Yep, more than one way to skin a cat.

##### Share on other sites
1 hour ago, benanamen said:

I am wondering why you would be introducing strings when this is specifically about int's. IMO is_int should be used instead of ctype_digit.

The OP never stated "where" the value is coming from. If the value is coming from a POST/GET variable it will ALWAYS be a string and always fail the is_int() test - even if the value is something like "5". If the value is specifically cast as an integer then there would be no reason to even test if it is an integer to begin with. So, it would only make sense to test if the value "looks" like an integer when it is an unknown string value that can be a string representation of an integer or some other invalid value. @Barand's test makes more sense.

##### Share on other sites
2 hours ago, Psycho said:

The OP never stated "where" the value is coming from.

Which is why you cant say "@Barand's test makes more sense." Based on OP's code, he expects there could be a negative int, otherwise he wouldn't be checking for it.

If "int" is negative, @Barands solution will fail (false).

`var_dump(ctype_digit('-128')); // False`

Casting the string to an int wouldn't work either.

`\$x =  (int) '5';`

Yes , it will make it an int and support negative values, but it will cast "anything" you put in there into an int such as the following and then you cannot check if it is a real int.

`\$x =  (int) 'xx'; // int 0`

So what to do then? One option that also addresses the source as a string argument would be the following.

```function fact(\$x): int
{
return \$x <= 1 ? 1 : \$x * fact(\$x - 1);
}

\$x = '-2147483648';// OK
\$x = -2147483648;// OK
\$x = 5; // OK
\$x = '5';// OK
\$x = 'ABC'; // Fail: Please provide an integer
echo (filter_var(\$x, FILTER_VALIDATE_INT) === 0 || filter_var(\$x, FILTER_VALIDATE_INT)) ? fact(\$x) : 'Please provide an integer';```

Edited by benanamen

##### Share on other sites
On 12/20/2019 at 3:37 PM, benanamen said:

Which is why you cant say "@Barand's test makes more sense." Based on OP's code, he expects there could be a negative int, otherwise he wouldn't be checking for it.

If "int" is negative, @Barands solution will fail (false).

If the value is a negative integer - it should fail. Factorials of negative numbers is not possible (e.g. division by zero) - unless you want to get into abstract complex numbers which would require the use of the gamma function.

The only valid values for a factorial are positive integers from zero to ∞. The only exception I can think of to the ctype_digit() test would be if you wanted to allow a plus symbol; in which case you would still need to remove it during the computation.

##### Share on other sites
1 hour ago, Psycho said:

Factorials of negative numbers is not possible

Thanks @Psycho. Shows how much I knew about Factorials, lol.

##### Share on other sites
On 12/20/2019 at 9:37 PM, benanamen said:

Based on OP's code, he expects there could be a negative int, otherwise he wouldn't be checking for it.

He's testing for 0 or 1.

0! and 1! both equate to 1, so no need to calculate any further.

Every recursive function needs a stop condition otherwise you quickly overflow the stack with an infinite recursion.

## Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

×   Pasted as rich text.   Restore formatting

Only 75 emoji are allowed.

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×

×

• #### Activity

• Chat
×
• Create New...