Determining Number of Factors in PHP
- February 2nd, 2010
- By AMB
- Write comment
I’m currently learning PHP. It’s not the first dynamically typed language I’ve worked in (I’m pretty handy in JavaScript), but I definitely do the lion’s share of my hacking in statically typed languages. (These days, mostly C#). The below code is hardly revolutionary, but it works well enough. And suggestions for improving it are most welcome.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | function DetermineNumFactors($numberToCheck) { if($numberToCheck == 1) { return 1; } $numberRoot = sqrt($numberToCheck); $numFactors = 2; for($i = 2; $i < $numberRoot; $i++) { if($numberToCheck % $i == 0) { $numFactors++; } } //we have all the factors up to, but not including the square root $numFactors *= 2; //now we have all the factors above and below the square root. if(floor($numberRoot) == $numberRoot) { //if root is a natural number, then it's a factor $numFactors++; } return $numFactors; } |
One notable bit is the floor/ceiling comparison. I needed to check to see if the root is a natural number. (If the square root of the number is a natural number, then the square root of the number is also one of its factors.) Comparing the square root’s floor and ceiling was the first solution that popped into my head.
I had considered just modding the number by one and comparing the result to zero, but the mod operator truncates floats before performing the modulus, so ($foo % 1) will always return zero.If anyone has a better solution, please let me know.
UPDATE: Two improvements to the method above from the comment section. Andy makes the excellent point that my factorization can start from two, since one and the number itself will always be factors. In order to make this work, I also have to then include an if to handle the boundary case for if the $numberToCheck argument is one.
Chris astutely pointed out that my ceil() check is superfluous and that I can get by with just if (floor($numberRoot) == $numberRoot).
Thank you both for your feedback.
