The increment $e in a for loop is more of an infinite while(1) .
So instead of using the increment in pow() incorrectly, do pow yourself, just multiplying iteration once. Calling pow() can be quite expensive, so calculating your own pow better distributes the multiplication over each iteration.
Edit: Below is a variant of your function that distributes the calculation of pow() by iteration. In addition, it makes the initialization of variables more correct (for example, the return value has not been set), reports that if $min and $max are reversed and corrects this, instead of abs instead of ternary, an exception is thrown if an invalid value was specified for log() , renamed to some variables and added $num to the return value as a key to first save the array_unique operation at the end:
function range_multistep($min, $max, Array $steps, $jmp = 10) { $range = array(); if (!$steps) return $range; if ($min < $max) { trigger_error(__FUNCTION__.'(): Minima and Maxima mal-aligned.', E_USER_NOTICE); list($max, $min) = array($min, $max); } $steps = array_unique($steps); sort($steps, SORT_NUMERIC); $bigstep = abs($jmp); if ($bigstep === 0) { throw new InvalidArgumentException(sprintf('Value %d is invalid for jmp', $jmp)); } $initExponent = ($min > 0) ? floor(log($min, $bigstep)) : 0; for ($multiplier = pow($bigstep, $initExponent); ; $multiplier *= $bigstep) { foreach ($steps as $step) { $num = $step * $multiplier; if ($num > $max) { break 2; } elseif ($num >= $min) { $range[$num] = 1; } } } $range = array_keys($range); sort($range, SORT_NUMERIC); return $range; }
In case you feel experimental, it is also possible to turn two loops ( for + foreach ) into one, but the readability of the code does not bring him any benefit:
for( $multiplier = pow($bigstep, $initExponent), $step = reset($steps) ; $num = $step * $multiplier, $num <= $max ;
I think that if you take care not to reuse the variables (for example, the function parameter) and give them better read names, the improvement comes to it yourself.