n factorial issue with large number - php

I have written the following code for finding n!. I am running this through CLI.
<?php
$handle = fopen("php://stdin", "r");
$number = (int) trim(fgets($handle));
$fact = calcFactorial($number);
echo $fact . "\n";
function calcFactorial($number) {
if ($number < 2) {
return 1;
} else {
return $number * calcFactorial($number - 1);
}
}
fclose($handle);
?>
The above code is working fine. But there are two issues with two different PHP installations.
On one PC I get,
Fatal error: Maximum function nesting level of '100' reached,
aborting!
To correct above problem I find the solution here. Is this the correct way to have a solution? Because it depends on a particular Default Value of 'xdebug.max_nesting_level' .
On other PC I get,
INF
So what is the best approach to tackle this issue?
P.S.: I have gone through various solutions throughout this website but I am not able to conclude.
UPDATE: There is one function suggested. But can it be done without using any kind of function?

Nesting limit:
if the calcFactorial() can by non-recursive then you can change it to this:
function calcFactorial($number){
if($number<2){
return 1;
}
$ret = 1;
for($i=2;$i<=$number;$i++){
$ret = $ret*$i;
}
return $ret;
}
if has to be recursive you never be able to calc factorial of number bigger then Maximum function nesting level.
INF:
That means PHP thinks number is infinitive (to big to store in memory) ... i think (not sure) that answer is bigger than PHP_INT_MAX ...
You can confirm this by echo is_infinite($number);
you can try solve this with storing numbers as strings (of digits) or arrays (of digits) and than write some function to make multiplication of this strings (arrays) but it is not easy to do

Related

Better "Randomization" with Simplexml and PHP

I'm working on a 'thought' function for a game i'm working on -- it pulls random strings from an XML file, combines them and makes them 'funny'. However, i'm running into a small issue in that the same couple of items keep getting selected each time.
The two functions I am using are
function randRoller($number)
{
mt_srand((microtime()*time())/3.145);
$x = [];
for($i = 0; $i < 100; $i++)
{
#$x = mt_rand(0,$number);
}
return mt_rand(0,$number);
}
/* RETRIEVE ALL RELEVANT DATA FROM THE XML FILE */
function retrieveFromXML($node)
{
$node = strtolower($node);
$output = [];
$n = substr($node,0,4);
#echo $node;
foreach($this->xml->$node->$n as $data)
{
$output[] = $data->attributes();
}
$count = count($output)-1;
$number = $this->randRoller($count);
return $output[$number];
}
Granted, the "randRoller" function is sorta defunct now because the orginal version I had (Which 'rolled' ten numbers from the count, and then selected the one which got the most number of dice) didn't work as planned.
I've tried everything i can think of to get better results && have googled my brains out to fix it. but still am getting the same repetitive results.
Don't use mt_srand() unless you know what you are doing, since it is called automatically. See the note on http://php.net/manual/en/function.mt-srand.php:
Note: There is no need to seed the random number generator with srand() or mt_srand() as this is done automatically.
Remove (all) the mt_srand() call(s).

Recursive Search of Directories php

Wow, StackOverFlow does a great job even AJAX search of topics and answered questions as I type in the title. Truly worthy programmers.
The code follows. It works just fine, when I set max recursion to 0. So it seems obvious that the problem is in my recursion code. But i can't find it.
I considered that opendir might return a handle that is global and I was stepping on it in the next recursion, so I set the recursion outside the opendir handle. No recursion is called with a handle open and it still produces nothing when max recursion is more than zero. I even added a max opened dir. As you see that variable pass down through the recursions, it will not opendir if $maxopendir is zero. If that were the problem, I would still get something back. But I get nothing, unless of course $maxrecursions is 0, then its fine and returns all files or directory names in HOME directory that match the search term.
Any experts on recursion that can correct me?
$dircontent.= searchalldirectories(HOME, $_POST['search'], 0, 5);
function searchalldirectories($directory, $seachterm, $maxrecursions, $maxopendir){
$dircontent= '';
$dirs= array();
if ($maxopendir>0){
$maxopendir--;
$handle= opendir($directory);
while (($dirlisting= readdir($handle))!==false){
$dn= ''; $fn= ' File';
if (is_dir($directory.'/'.$dirlisting) && $maxrecursions>0){
$dirs[count($dirs)]= $directory.'/'.$dirlisting;
$dn= '/'; $fn= 'Dir';
}
if (stripos($dirlisting, $seachterm)!==false){
$dircontent.= '<input type="image" src="go.jpg" name="cmd" value="home:/'.$dirlisting.'"> '.$fn.':// <b>'.$dirlisting.$dn.'/</b><br>';
}
}
closedir($handle);
for ($i=0; $i<count($dirs); $i++){
$dircontent.= searchalldirectories($dirs[$i], $s, ($maxrecursions-1), $maxopendir);
}
}
return $dircontent;
}
Your loop appears to be running away with itself when the opendir fails. You may try testing the return value like so:
if(!($handle= opendir($directory))) {
echo "Could not opendir($directory)\n";
return false;
}

Weird pow() php bug

I have this piece of php code:
$skill_amount = round(pow($rarity,1.25));
It should be noted that $rarity is derived from a query.
I am inputting values like 0,2,4,8,16,32,64 into it.
99% of the time it is working but a small amount of times my users are reporting huge values like:
13771, 77936
What could possibly be causing this?
"What could possibly be causing this?"
A large or unexpected value for $rarity.
If you can inspect all possible values of $rarity, you should do that. Otherwise, you could do some basic debugging.
if ($skill_amount > some sane value) {
// log $skill_amount & $rarity to a file or email
// maybe also some other investigative values, like stuff that assisted the derivation of $rarity
}
No trouble found in this script, so I would agree with the need for sanity checks on $rarity.
<?php // RAY_temp_amy_neville.php
error_reporting(E_ALL);
echo '<pre>';
$range = range(1, 4096);
foreach ($range as $rarity)
{
$skill_amount = round(pow($rarity,1.25));
$out[$rarity] = $skill_amount;
}
print_r($out);

Purpose of PHP parameters

I am trying to grasp the concept of PHP functions. I know how to create one.
function functionName()
{
//code to be executed;
}
I also know how to call a function. I am just a little confused as to what a parameter is for. I have read the php manual and w3schools.com's tutorial. From my understanding, you need a parameter to pass a value to the function? If that is correct why not just create it within the function? Why use a parameter?
Like this:
<?php
function num()
{
$s=14;
echo $s;
}
num();
?>
I know you can do:
<?php
function num($s=14)
{
echo $s;
}
num();
?>
or:
<?php
function num($s)
{
echo $s;
}
num($s=14);
?>
Could someone give me a real application of using a parameter, for say maybe a user based dynamic content website? I think it would help me understand it better.
Passing a parameter allows you to use one function numerous times. For example:
If you wanted to write ONE function that sent mail - you could pass the following parameters:
$to = $_POST['to'];
$from = $_POST['from'];
$subject = $_POST['subject'];
Then, in your function:
function sendmail($to, $from, $subject){
//code to be executed
}
Now you can reuse your send function at various points in your web app.
Here is an example, say you have numbers representing colors (this is common in storing data in a database) and you want to output what number represent's what color.
Say you had to do this a hundrend times for a hundred numbers.
You'd get pretty tired writing 100 if statments 100 times.
Here is a function example...
function colorType($type) {
if ($type == 1) {
return "Green";
}
elseif ($type == 2) {
return "Blue";
}
elseif ($type == 3) {
return "Red";
}
// etc
}
echo colorType(1) . "<br>"; // Green
echo colorType(2) . "<br>"; // Blue
echo colorType(3) . "<br>"; // Red
A function does something, and gives a result. It may accept parameters to arrive at that result, it may not. The simple calculator, as aforementioned, is a good one.
The easiest way to understand functions and parameters is to just read the PHP manual—most of the functions in the core PHP language take parameters of some sort. These functions are no different to the functions you write.
Let's assume you want to create a function that will allow people to sum numbers, you can't write needed variables in functions because you want others to input it and your function shows output:
function add($num1, $num2){
return $num1 + $num2;
}
Now anyone can call/use your function to sum numbers:
echo add(5,1); // 6
echo add(2,1); // 3
echo add(15,1); // 16
That's the most simplest example one can give to explain why you need parameters :)
When you specify function name($var=VALUE), you are setting a default.
function doit($s=14) {
return $s + 5;
}
doit(); // returns 19
doit(3); // returns 8
it makes your functions flexible to be reused in various situations, otherwise you would have to write many functions, one for each scenario. this is not only tedious, but becomes a nightmare if you have to fix something in those functions. instead of fixing it in one place, you would have to fix it in many places. you basically never want to have to copy paste code you have already written, instead you use arguments to make one set of the code flexible enough to handle each situation.
Paramaters allow your function to see the value of variables that exist outside of itself.
For example:
function F_to_C($temp) {
$temp = ($temp - 32) / 1.8;
return $temp;
}
$temperature = 32;
$new_temperature = F_to_C($temperature); // 0
echo $temperature;
$temperature2 = F_to_C(212); // 100
echo $temperature2;
Here we take $temperature, which we define in the code, but could be user input as from a form, and then send it to the function F_to_C. This allows us to convert it to Celsius, so we can then display it thereafter. In the next section, we then re-use the function to convert the boiling point, which is sent directly this time as the value 212. If we had embedded $temperature = 32 in the function the first time, then we would still get 0 as a result. However since we're using parameters, we instead get 100 back, because it's processing the value we specified when we invoked the function.

Script dies, I'm not sure why

I'm trying to parse a 6,000 line 500 KB file into an array so I can import the data into our system. The problem is that the script stops executing somewhere between lines 3000-4000. There are no breaks in the code, we use it on other imports. Any ideas on why this might be happening and what I can do to prevent it?
/**
* Takes a seperated value string and makes it an array
* #param $delimiter string The delimiter to be seperated by, usually a comma or tab
* #param $string string The string to seperate
* #return array The resulting array
*/
public function svToArray ($delimiter, $string) {
$x = 0;
$rowList = array();
$splitContent = preg_split("#\n+#", trim($string));
foreach ($splitContent as $key => $value) {
$newData = preg_split("#".$delimiter."#", $value);
if ($x == 0) {
$headerValues = array_values($newData);
} else {
$tempRow = array();
foreach ($newData as $rowColumnKey => $rowColumnValue) {
$tempRow[$headerValues[$rowColumnKey]] = $rowColumnValue;
}
$rowList[] = $tempRow;
}
$x++;
}
return $rowList;
}
UPDATE:
Error reporting is enabled. I've started using a file that's only 130KB at 1,500 lines and it does the same thing...
When I add debug code as in the following example nothing echoes at all unless I put an exit after the echo "test<br/>";
public function svToArray ($delimiter, $string) {
$x = 0;
$rowList = array();
$splitContent = preg_split("#\n+#", trim($string));
echo "test<br/>";
foreach ($splitContent as $key => $value) {
$newData = preg_split("#".$delimiter."#", $value);
if ($x == 0) {
$headerValues = array_values($newData);
} else {
$tempRow = array();
foreach ($newData as $rowColumnKey => $rowColumnValue) {
$tempRow[$headerValues[$rowColumnKey]] = $rowColumnValue;
}
$rowList[] = $tempRow;
}
$x++;
}
echo "test";
$this->tru->debug($rowList);
exit;
return $rowList;
}
UPDATE
If I comment out $tempRow[] = $rowColumnValue; then it echoes everything fine....
Probably it just timeouts. Does it always stop after X seconds?
Try setting the max execution time higher: set_time_limit(900) at the top of your pages.
You can check the max execution time in your phpinfo():
1. Create a new php page with
2. Search for max_execution_time
Have you looked at the files? Is there a line with too many delimiters? Also, what are all the "#" about?
My best guess is that you're hitting a line where $headerValues[$rowColumnKey] is not defined.
What about $rowColumnKey and $rowColumnValue ?
They are not defined in the function.
Make sure that you have error reporting set, put this on top of your php file:
ini_set('display_errors', true);
error_reporting(E_ALL);
Also you can extend the script's execution time:
ini_set('max_execution_time', 50000);
About the only time I've a php script die, with no output and no errors is when it runs out of memory. It doesn't look like your script would use much memory, but I would check to make sure that the memory limit for php is high enough.
Are you sure that you are iterating through the returned array instead of simply trying to print it? (The issue may be outside of the function rather than within it.)
Also...
`exit;
return $rowList;`
Try removing the 'exit;' line and see if that changes anything.
Also, $splitContent is not defined as an array before being used, but preg_split is going to return an array. (This should not impact your results, but it is safe to do so.)
Why are you using $key => $value pairs when you cannot be sure of what will be within the string? If we could see an small example of the content of $string, we might be able to adjust this function to work better.
The # should be replaced with /, but that may simply be a formatting issue.
$newData should be defined as an array before being used just to be safe even though that is not causing your issue.
If you can, increase maximum execution time in php.ini.. also increase the maximum memory amount for each instance.. checking error logs of your webserver could also help.
It appears as though there was too much output to the output buffer, causing the page to show nothing at all.

Categories